为什么这个makefile不起作用?

时间:2013-04-12 08:46:13

标签: makefile gnu-make

我是Makefiles的新手,我正在尝试编写一个简单的编译和链接变量中列出的所有应用程序,如下所示:

APPLICATIONS = app1 app2 app3

所有这些文件都必须有一个源文件(.c)并使用我在同一个Makefile中定义的CFLAGS和LDFLAGS进行编译,但由于某种原因,它无法正常工作......代码基于示例找到here(第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 '------------------: $< -> $@ : '
    if [ $(TOOLCHAIN) $< -o $(OBJDIR)/$@ $(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 个答案:

答案 0 :(得分:2)

您有两条规则:

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

$(OBJS): | $(OBJDIR)

第一个是模式规则,第二个是常规规则。通常它们可以一起工作,但如果源文件(one.ctwo.c,three.c`)不存在,那么第一条规则不适用,第二条规则要求构建目录,这就是你得到的。你也可以将它们结合起来:

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

或更好:

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

一旦你理顺了,你会发现另一个问题。此规则中的命令:

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

不要做你认为他们做的事。如果@printf ...在您的shell中有效,则第一个(printf)将起作用;您应该测试一下,如果没有,请尝试@echo ...。接下来的四行显然是为了共同努力。但是在Make规则中,每一行都是一个命令,在自己的子shell中运行,所以这个结构不起作用。你可以将整个事情放在一行:

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

(请注意分号。)这是一条很长的线,所以如果眼睛很难看,你可以用反斜杠将它分开来指示线延续:

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

(请注意,if前面只需要一个TAB。)

答案 1 :(得分:0)

它不起作用,因为文件one.ctwo.cthree.c不存在,因此不必构建它们。