使用make对每个源文件执行操作

时间:2016-09-22 17:10:13

标签: makefile gnu-make sdcc

我创建了一个像这样的Makefile

CC = sdcc
SRCS = $(PNAME).c\
    ../../src/gpio.c
    ../../src/timers.c
    ../../src/i2c.c
$HDRS = -I../../headers

all:
    mkdir -p ./output
    $(CC) $(SRCS) -lstm8 -mstm8 $(HDRS)

问题是,sdcc一次只能编译一个源。所以我需要在SRCS变量中定义的每个源上执行类似foreach的操作。如何在gnu-make中执行此操作?

2 个答案:

答案 0 :(得分:2)

使用patsubst。通常情况如下:

SOURCES := $(wildcard *.c)
OBJECTS := $(patsubst %.c,%.o,${SOURCES})
prog: ${OBJECTS}
        cc $^ -o $@
%.o: %.c
        cc $< -c -o $@

答案 1 :(得分:2)

根据the docs,您必须分别编译包含main()的文件以生成.rel文件,然后将其包含在主文件的编译命令中。关于如何做到这一点有几种变化。以下内容避免了特定于GNU make的功能:

# We're assuming POSIX conformance
.POSIX:

CC = sdcc

# In case you ever want a different name for the main source file    
MAINSRC = $(PMAIN).c

# These are the sources that must be compiled to .rel files:
EXTRASRCS = \
    ../../src/gpio.c \
    ../../src/timers.c \
    ../../src/i2c.c

# The list of .rel files can be derived from the list of their source files
RELS = $(EXTRASRCS:.c=.rel)

INCLUDES = -I../../headers
CFLAGS   = -mstm8 
LIBS     = -lstm8 

# This just provides the conventional target name "all"; it is optional
# Note: I assume you set PNAME via some means not exhibited in your original file
all: $(PNAME)

# How to build the overall program
$(PNAME): $(MAINSRC) $(RELS)
    $(CC) $(INCLUDES) $(CFLAGS) $(MAINSRC) $(RELS) $(LIBS)

# How to build any .rel file from its corresponding .c file
# GNU would have you use a pattern rule for this, but that's GNU-specific
.c.rel:
    $(CC) -c $(INCLUDES) $(CFLAGS) $<

# Suffixes appearing in suffix rules we care about.
# Necessary because .rel is not one of the standard suffixes.
.SUFFIXES: .c .rel

顺便说一句,如果你仔细观察,你会发现文件没有显式地对源文件或任何此类事物进行任何循环。它只描述了如何构建每个目标,包括中间目标。 make自己计算如何将这些规则结合起来,从源头到最终计划(或者你指定的任何其他目标,你已经教过它们建立)。