1. 程式人生 > >Makefile中使用 for 控制結構編譯多個目標檔案

Makefile中使用 for 控制結構編譯多個目標檔案

假如,有很多檔案,每個檔案都要變成一個單獨的目標檔案,如果使用makefile的話,最好能用一個 for 迴圈來做。

makefile是支援使用 for的。

先假定有下面幾個檔案:

a.h  b.h  test1.cpp  test2.cpp

$ cat a.h 
#ifndef A_H
#define A_H
class A
{
public:
void Do(void){}
};
#endif

 $ cat b.h 
#ifndef B_H
#define B_H
class B
{
public:
	void Do(){}
};
#endif
$ cat test1.cpp 

#include "a.h"

int main(void)
{
	A a;
	a.Do();
	return 0;
}


$ cat test2.cpp 
#include "b.h"

int main(void)
{
	B b;
	b.Do();
	return 0;
}

Makefile可寫成如下的形式:
CXX = g++
CXXFLAGS = -g -I. -Wall
SRCS = test1.cpp test2.cpp
OBJECTS = $(SRCS:%.cpp=%.o)
TARGETS = $(SRCS:%.cpp=%)
all : $(TARGETS)
	@for target in $(TARGETS); \
	do                        \
	$(CXX) $(CXXFLAGS) -o $$target $$target.cpp; \
	done
clean:
	-rm -f $(TARGETS) $(OBJECTS)
$ make
g++ -g -I. -Wall    test1.cpp   -o test1
g++ -g -I. -Wall    test2.cpp   -o test2

其中

TARGETS = $(SRCS:%.cpp=%)

相當於

TARGETS = $(patsubst %.cpp,%,$(SRCS))

需要說明的幾點:

1. 因為 for屬於 shell 命令,所以這裡的target變數需要再加上一個$ , 確保shell接收到的是 $target (makefile會先把 $$target 處理為 $target, 傳給shell).

2. 因為,makefile的 target對應的 命令,每一行都是在一個單獨的subshell裡執行,所以,如果想要 shell 變數始終是可見的話,需要加一個反斜線,表示這些命令是在一個 subshell裡執行。