具有多个可执行文件的Makefile

我正在尝试编写一个使用macros从一个多个文件创build多个可执行文件的makefile。 我试着通过以前回答的问题寻找,但是,因为我对C编程和gcc工作相当新,我无法find我的问题的答案。

这是我到目前为止:

CC=gcc CFLAGS=-I. OBJ = ex1.c ex3.c EXECUTABLE = ex1 ex3 $(EXECUTABLE): $(OBJ) gcc -o $@ $^ $(CFLAGS) clean: rm -f $(EXECUTABLE) 

我想要这条线

 $(EXECUTABLE): $(OBJ) 

分别从文件ex1.c ex3.c创build可执行文件ex1和ex3。

对于这种特殊情况,每个可执行文件都有一个扩展名为.c的单个源文件,您只需要一行Makefile:

 all: ex1 ex3 

make的内置默认规则已经工作:

 $ make cc -O2 -pipe ex1.c -o ex1 cc -O2 -pipe ex3.c -o ex3 

在幕后, make使用了POSIXly强制的内置单个后缀规则

 .c: $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< 

根据你的喜好改变命令make CC=gcc CFLAGS=-O2 LDFLAGS=-s和类似的命令。

琐事:实际上,如果您在调用make时想要命名目标,则可以使用空白或甚至没有任何Makefile的情况下运行

 $ make -f /dev/null CC=gcc CFLAGS=-O2 LDFLAGS=-s ex1 ex3 gcc -O2 -s ex1.c -o ex1 gcc -O2 -s ex3.c -o ex3 $ rm -f Makefile ex1 ex3 $ make CC=gcc CFLAGS=-O2 LDFLAGS=-s ex1 ex3 gcc -O2 -s ex1.c -o ex1 gcc -O2 -s ex3.c -o ex3 

做魔术!

作为一个经验法则,不要重新发明轮子(或规则),使用已经存在的规则。 它简化了你的生活。 这使得小和性感的makefiles打动女士:-)

一些build议(假设你使用GNU make ,而不是别的)

首先,运行一次make -p ,你就会明白内build的规则是怎么知道的。 请特别COMPILE.cLINK.c

那么,我build议

  CFLAGS= -g -Wall -I. 

(因为你真的想要-g进行debugging,并且-Wall获得大部分警告)

而你可能不需要

 $(EXECUTABLE): $(OBJ) gcc -o $@ $^ $(CFLAGS) 

不过,我build议在大多数其他规则之前添加

 .PHONY: all clean all: $(EXECUTABLES) 

实际上,我会为你的Makefile (用于GNU make !)编码如下

 # file Makefile CC= gcc RM= rm -vf CFLAGS= -Wall -g CPPFLAGS= -I. SRCFILES= ex1.c ex2.c ## or perhaps $(wildcard *.c) OBJFILES= $(patsubst %.c, %.o, $(SRCFILES)) PROGFILES= $(patsubst %.c, %, $(SRCFILES)) .PHONY: all clean all: $(PROGFILES) clean: $(RM) $(OBJFILES) $(PROGFILES) *~ ## eof Makefile 

请记住, 制表符Makefile -s( 规则的动作部分)中的重要特征。 在这个答案中,以四个空格开始的行至less应该以制表符开头。

一旦所有的东西都被debugging了,考虑运行make clean来清理所有东西,然后make -j CFLAGS=-O2 all并行编译并进行优化。

最后,我推荐使用remake并运行remake -x来debugging复杂的Makefile -s

当然,我假设你的目录只有单文件程序。

顺便说一句,还有其他的build设者计划。 也许你可能会考虑omake

不要忘记使用像git这样的版本控制系统来处理源文件。 现在是学习这种工具的时候了。

你很近,但你需要一个模式规则:

 $(EXECUTABLE): % : %.c 

然后一个默认的规则,使它build立两个:

 all: $(EXECUTABLE) 

以下答案包括多个可执行文件,如启动,进程1,进程2,…,进程4。

 LOCAL_INCLUDE=./ all: clean process_first process_second init process_first: gcc -g -o process1 -I$(LOCAL_INCLUDE) process1.c -lzmq -L. -L./. gcc -g -o process2 -I$(LOCAL_INCLUDE) process2.c -lzmq -L. -L./. process_second: gcc -g -o process3 -I$(LOCAL_INCLUDE) process3.c -lzmq -L. -L./. gcc -g -o process4 -I$(LOCAL_INCLUDE) process4.c -lzmq -L. -L./. init: gcc -g -o initiate -I$(LOCAL_INCLUDE) initiate.c -lzmq -lconfig -lpthread -L. -L./. -ldl -lrt clean: rm -rf init_manager.o init_manager rm -rf process1 process2 process3 process4 

注意:这是一个很好的做法,清理并触及所有可执行文件,然后重新制作。