A Simple Makefile Tutorial

来源:互联网 发布:sql语句删除表 编辑:程序博客网 时间:2024/05/16 02:13

A Simple Makefile Tutorial

Makefiles are a simple way to organize code compilation. This tutorialdoes not even scratch the surface of what is possible usingmake, but is intended as a starters guide so that you canquickly and easily create your own makefiles for small to medium-sizedprojects.

A Simple Example

Let's start off with the following three files, hellomake.c,hellofunc.c, and hellomake.h, which would represent a typical mainprogram, some functional code in a separate file, and an include file,respectively.

hellomake.chellofunc.chellomake.h
#include int main() {  // call a function in another file  myPrintHelloMake();  return(0);}
#include #include void myPrintHelloMake(void) {  printf("Hello makefiles!\n");  return;}
/*example include file*/void myPrintHelloMake(void);

Normally, you would compile this collection of code by executing the following command:

gcc -o hellomake hellomake.c hellofunc.c -I.

This compiles the two .c files and names the executable hellomake. The-I. is included so that gcc will look in the currentdirectory (.) for the include file hellomake.h. Without a makefile,the typical approach to the test/modify/debug cycle is to use the uparrow in a terminal to go back to your last compile command so youdon't have to type it each time, especially once you've added a fewmore .c files to the mix.

Unfortunately, this approach to compilation has two downfalls. First,if you lose the compile command or switch computers you have to retypeit from scratch, which is inefficient at best. Second, if you are onlymaking changes to one .c file, recompiling all of them every time isalso time-consuming and inefficient. So, it's time to see what we cando with a makefile.

The simplest makefile you could create would look something like:

Makefile 1
hellomake: hellomake.c hellofunc.c     gcc -o hellomake hellomake.c hellofunc.c -I.

If you put this rule into a file called Makefile ormakefile and then typemake on the command line itwill execute the compile command as you have written it in themakefile. Note thatmake with no arguments executes the firstrule in the file. Furthermore, by putting the list of files on whichthe command depends on the first line after the:, make knowsthat the rulehellomake needs to be executed if any of thosefiles change. Immediately, you have solved problem #1 and can avoidusing the up arrow repeatedly, looking for your last compilecommand. However, the system is still not being efficient in terms ofcompiling only the latest changes.

One very important thing to note is that there is a tab before the gcccommand in the makefile. There must be a tab at the beginning of anycommand, andmake will not be happy if it's not there.

In order to be a bit more efficient, let's try the following:

Makefile 2
CC=gccCFLAGS=-I.hellomake: hellomake.o hellofunc.o     $(CC) -o hellomake hellomake.o hellofunc.o -I.

So now we've defined some constants CC andCFLAGS. It turns out these are special constants thatcommunicate tomake how we want to compile the fileshellomake.c and hellofunc.c. In particular, the macroCC isthe C compiler to use, and CFLAGS is the list of flags topass to the compilation command. By putting the objectfiles--hellomake.o and hellofunc.o--in the dependency list and in therule,make knows it must first compile the .c versionsindividually, and then build the executable hellomake.

Using this form of makefile is sufficient for most small scaleprojects. However, there is one thing missing: dependency on theinclude files. If you were to make a change to hellomake.h, forexample,make would not recompile the .c files, even thoughthey needed to be. In order to fix this, we need to tellmakethat all .c files depend on certain .h files. We can do this bywriting a simple rule and adding it to the makefile.

Makefile 3
CC=gccCFLAGS=-I.DEPS = hellomake.h%.o: %.c $(DEPS)$(CC) -c -o $@ $< $(CFLAGS)hellomake: hellomake.o hellofunc.o gcc -o hellomake hellomake.o hellofunc.o -I.

This addition first creates the macro DEPS, which is the set of .hfiles on which the .c files depend. Then we define a rule that appliesto all files ending in the .o suffix. The rule says that the .o filedepends upon the .c version of the file and the .h files included inthe DEPS macro. The rule then says that to generate the .o file,make needs to compile the .c file using the compiler definedin the CC macro. The -c flag says to generate the object file, the-o $@ says to put the output of the compilation in the filenamed on the left side of the :, the $< is the first item inthe dependencies list, and the CFLAGS macro is defined as above.

As a final simplification, let's use the special macros $@and $^, which are the left and right sides of the:,respectively, to make the overall compilation rule more general. Inthe example below, all of the include files should be listed as partof the macro DEPS, and all of the object files should be listed aspart of the macro OBJ.

Makefile 4
CC=gccCFLAGS=-I.DEPS = hellomake.hOBJ = hellomake.o hellofunc.o %.o: %.c $(DEPS)$(CC) -c -o $@ $< $(CFLAGS)hellomake: $(OBJ)gcc -o $@ $^ $(CFLAGS)

So what if we want to start putting our .h files in an includedirectory, our source code in a src directory, and some locallibraries in a lib directory? Also, can we somehow hide thoseannoying .o files that hang around all over the place? The answer, ofcourse, is yes. The following makefile defines paths to the includeand lib directories, and places the object files in an objsubdirectory within the src directory. It also has a macro definedfor any libraries you want to include, such as the math library-lm. This makefile should be located in the srcdirectory. Note that it also includes a rule for cleaning up yoursource and object directories if you typemake clean. The.PHONY rule keepsmake from doing something with a file namedclean.

Makefile 5
IDIR =../includeCC=gccCFLAGS=-I$(IDIR)ODIR=objLDIR =../libLIBS=-lm_DEPS = hellomake.hDEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))_OBJ = hellomake.o hellofunc.o OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))$(ODIR)/%.o: %.c $(DEPS)$(CC) -c -o $@ $< $(CFLAGS)hellomake: $(OBJ)gcc -o $@ $^ $(CFLAGS) $(LIBS).PHONY: cleanclean:rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 

So now you have a perfectly good makefile that you can modify tomanage small and medium-sized software projects. You can add multiplerules to a makefile; you can even create rules that call otherrules. For more information on makefiles and themakefunction, check out the GNU Make Manual, which will tell you more than you ever wanted to know (really).


原文地址: http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 怎么查自己宽带账号密码忘了怎么办 电脑重置路由器密码连不上网怎么办 e盘和f盘没有了怎么办 复制文件过程中自己卡住了怎么办 电脑卡住了怎么办 鼠标也点不动 善领wifi连上网不能用怎么办 苹果手机软件更新后网速太慢怎么办 装了固态硬盘开机还慢怎么办 华为荣耀8青春版玩游戏卡怎么办 光猫自带wifi网络很差怎么办 侠盗猎车手自由城之章卡退怎么办? 夏天带头盔晃眼睛太厉害怎么办 别人把钱误转我卡上我怎么办? 家里预留的的网线太短怎么办 电信路由器坏了网线接口断了怎么办 数据线充手机的接头处断了怎么办 新买的小米手环充不进去电怎么办 绝地求生手游被队友故意炸死怎么办 一加3t屏幕开了怎么办? 孕妇吃了8个杏怎么办啊 洗碗盆落水器垫子密封不好怎么办? 手剥橙子剥的特别疼怎么办? 经常带对讲机的耳麦耳朵痛怎么办 公安检查遇到穿便装的军人怎么办 cf幽灵鬼呼吸辅军训刘海怎么办助 眼睛被等离子切割器的光烤了怎么办 玩王者的时候屏幕竖着了该怎么办 铝合金门双包门套比墙的厚了怎么办 磁共振检查后发现带金属了怎么办 贴了乳贴过免痒怎么办 yy别人听见我打游戏的声音怎么办 微信的聊天记录发错邮箱怎么办 百度云盘文件有违规内容怎么办 天籁一键启动钥匙没电怎么办 中兴手机系统界面已停止运行怎么办 怎么办可以复制成不关联的文档 希捷400g硬盘电机不转怎么办 金立手机微信语音播放失败怎么办 手机4g网络变2g怎么办 生存战争2吃了腐烂的食物后怎么办 古筝调音 d的显示为b怎么办