2013-04-12 195 views
0

我是新來的Makefile,我想寫一個簡單的一個,將編譯和鏈接的變量一樣,列出的所有應用程序:爲什麼這個makefile不起作用?

APPLICATIONS = app1 app2 app3 

它們都必須有一個源文件(.c)並使用我在同一個Makefile中定義的CFLAGS和LDFLAGS進行編譯,但由於某種原因,它不起作用...代碼基於一個發現的示例here(page 23)。

APPLICATIONS = one two three 

DESTDIR=/home/carles/Develop/xenomai-2.5.6 

TOOLCHAIN = arm-linux-gnueabi-gcc 

OBJDIR  := bin 
OBJS  := $(addprefix $(OBJDIR)/,$(addsuffix .o,$(APPLICATIONS))) 
INCLUDE_PATH = $(DESTDIR)/usr/xenomai/include 
CFLAGS  = -I$(INCLUDE_PATH) -D_GNU_SOURCE -D_REENTRANT -D__XENO__ -Wall -pipe 
POSIX_CFLAGS = -I$(INCLUDE_PATH)/posix 
LIB_PATH  = $(DESTDIR)/usr/xenomai/lib 
LIBRARIES = -lnative -lxenomai -lpthread -lrtdk -lrt 
LDFLAGS  = $(LIBRARIES) -L$(LIB_PATH) 
POSIX_LDFLAGS= -Wl,@$(LIB_PATH)/posix.wrappers -lnative -lpthread_rt -lxenomai -lpthread -lrt -L$(LIB_PATH) 


$(OBJDIR)/%.o : %.c 
    @printf '------------------: $< -> [email protected] : ' 
    if [ $(TOOLCHAIN) $< -o $(OBJDIR)/[email protected] $(CFLAGS) $(LDFLAGS) -L$(LIB_PATH) ] 
    then 
     @echo 'done!' 
    fi 

all: $(OBJS) | show_config 

$(OBJS): | $(OBJDIR) 

$(OBJDIR): 
    mkdir -p $(OBJDIR) 

show_config: 
    @echo '------------------: APPLICATIONS : $(APPLICATIONS)' 
    @echo '------------------: DESTDIR  : $(DESTDIR)' 
    @echo '------------------: INCLUDE PATH : $(INCLUDE_PATH)' 
    @echo '------------------: LIB. PATH : $(LIB_PATH)' 
    @echo '------------------: TOOLCHAIN : $(TOOLCHAIN)' 
    @echo '------------------: LIBRARIES : $(LIBRARIES)' 
    @echo '------------------: OBJS   : $(OBJS)' 

clean: 
    @rm $(OBJDIR) -r -f 

當我運行$ make只創建目錄和show_config被調用,但不創建對象文件和不顯示錯誤。這裏有什麼問題?

回答

2

你有兩個規則:

$(OBJDIR)/%.o : %.c 
    ... 

$(OBJS): | $(OBJDIR) 

首先是一個模式規則,第二個是正式規定。通常他們可以一起工作,但如果源文件(one.c,two.c,three.c`)不存在,那麼第一個規則不適用,第二個規則要求構建目錄,這就是你所得到的。您不妨將它們組合起來:

$(OBJDIR)/%.o : %.c | $(OBJDIR) 
    ... 

或者更好的是:

$(OBJS): $(OBJDIR)/%.o : %.c | $(OBJDIR) 
    ... 

一旦你得到理順,你會發現另一個問題。這條規則中的命令:

$(OBJDIR)/%.o : %.c 
    @printf '------------------: $< -> [email protected] : ' 
    if [ $(TOOLCHAIN) $< -o $(OBJDIR)/[email protected] $(CFLAGS) $(LDFLAGS) -L$(LIB_PATH) ] 
    then 
     @echo 'done!' 
    fi 

不要做你認爲他們做的事。第一個(@printf ...)將工作,如果printf在你的shell中工作;你應該測試一下,如果沒有,請嘗試@echo ...。接下來的四行顯然是一起工作的。但是在Make規則中,每行都是自己的命令,運行在自己的子shell中,所以這個結構將不起作用。你可以把整個事情上一行:

if [ $(TOOLCHAIN) ... ]; then @echo 'done!'; fi 

(注意分號。)這是一個長的線,因此,如果這是很難的眼睛,你可以用反斜槓來指示行要繼續分裂它:

if [ $(TOOLCHAIN) $< -o $(OBJDIR)/[email protected] $(CFLAGS) $(LDFLAGS) -L$(LIB_PATH) ]; \ 
    then \ 
    @echo 'done!'; \ 
    fi 

(請注意,只有一個TAB是必要的,在if前。)

0

它不起作用,因爲文件one.c,two.c,three.c不存在,因此它們不必被建立。