0

我是 Makefiles 的新手,我正在尝试编写一个简单的文件,它可以编译和链接这样的变量中列出的所有应用程序:

APPLICATIONS = app1 app2 app3

它们都必须有一个源.c文件(

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调用了,但没有创建目标文件,也没有显示错误。这里有什么问题?

4

2 回答 2

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 '------------------: $< -> $@ : '
    if [ $(TOOLCHAIN) $< -o $(OBJDIR)/$@ $(CFLAGS) $(LDFLAGS) -L$(LIB_PATH) ]
    then
        @echo 'done!'
    fi

不要做你认为他们做的事。如果在您的 shell 中工作,第一个 ( @printf ...) 将工作;printf您应该对此进行测试,如果没有,请尝试@echo ...。接下来的四行显然是为了协同工作。但是在 Make 规则中,每一行本身就是一个命令,在它自己的子 shell 中运行,所以这种结构不起作用。您可以将整个内容放在一行中:

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

(注意分号。)这是一条很长的线,所以如果眼睛很难看,您可以使用反斜杠将其分开来表示行继续:

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

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

于 2013-04-12T13:05:48.303 回答
0

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

于 2013-04-12T09:17:45.383 回答