从生成文件在构建目录中创建中间文件



我必须使用 makefile 在 Ubuntu 终端中制作一个 XC8 项目。 目录结构是这样的

Project/lib/GPIO/gpio.c
Project/lib/GPIO/gpio.h
Project/main.c
Project/Makefile
Project/build/lib/GPIO

生成文件正在项目目录本身中生成中间文件。实际上makefile将转到每个位置并为每个.c文件生成中间文件。

喜欢这个

Project/gpio.d
Project/gpio.p1
Project/gpio.pre
Project/<other files>

但我想在Project/build/lib/GPIO中生成它们。 即

Project/build/lib/GPIO/gpio.d
Project/build/lib/GPIO/gpio.p1
Project/build/lib/GPIO/gpio.pre
Project/build/<other files>

制作文件:

CHIP := 18F4580
CC := xc8
INCLUDE_PATH := /opt/microchip/xc8/v2.10/include/
PROG := /usr/share/tinybldlin/tinybldlin.py
PORT := /dev/ttyUSB0
AR := libr
SRC_DIR := $(wildcard *.c)
INC_DIR := $(wildcard *.h)
LIB_DIR := 
. 
lib 
lib/GPIO
BUILD_DIR := 
build/ 
build/lib/GPIO
TARGET := pic${CHIP}
FLASH_REGION := 0-3000
ifeq (${SRCS},)
SRCS := $(foreach libdir, $(LIB_DIR),  $(wildcard $(libdir)/*.c))
endif
ifeq (${INCS},)
INCS := $(foreach libdir, $(LIB_DIR),  $(wildcard $(libdir)/*.h))
endif
ifeq (${OBJS},)
OBJS := $(SRCS:.c=.obj)
endif
ifeq (${P1},)
OBJS := $(SRCS:.c=.p1)
endif
MIN_CFLAGS := --chip=${CHIP} -I${INCLUDE_PATH} --ROM=${FLASH_REGION}
# The following MSG_CFLAGS controls the compiler messages
MSG_CFLAGS := -Q
# The following OPT_CFLAGS reduces the code size
OPT_CFLAGS := --opt=all
# The following OUT_CFLAGS controls the generated outputs
OUT_CFLAGS := --asmlist --summary=psect,mem -M${TARGET}.map 
EXTRA_CFLAGS += ${MSG_CFLAGS} ${OPT_CFLAGS} ${OUT_CFLAGS}
CFLAGS := ${MIN_CFLAGS} ${EXTRA_CFLAGS} -DCOMPILER=${COMPILER}
ARFLAGS := r
${TARGET}.hex: ${OBJS}
${CC} ${CFLAGS} -intel $^ -o$@
${MAKE} xclean
${TARGET}.bin: ${OBJS}
${CC} ${CFLAGS} -bin $^ -o$@
${MAKE} xclean
%.p1: %.c ${INC_DIR}
${CC} ${CPPFLAGS} ${CFLAGS} --pass1 $<
%.obj: %.c ${INC_DIR}
${CC} ${CPPFLAGS} ${CFLAGS} -C $<
%.as: %.c ${INC_DIR}
${CC} ${CPPFLAGS} ${CFLAGS} -S $<
%.lib: %.obj
${AR} ${ARFLAGS} $@ $<

我要说的第一件事是,这个答案依赖于你使用 GNU make。 你没有确定你是,但既然你正在使用模式规则,我会这么假设。 请注意,使用标准 POSIX make 无法实现您想要执行的操作(除非您想为每个要构建的目标写出明确的规则(。

您需要两样东西:

  1. 告诉编译器您要执行的操作
  2. 告诉制作你想做什么

对于 #1,默认情况下编译器将生成输出,该输出是输入文件名减去扩展名(例如.c( 加上特定的扩展名(例如.as(。 由于输入文件lib/GPIO/gpio.c编译器会生成gpio.as。 大多数编译器都支持一个-o选项,该选项允许您重命名输出:如果这不起作用,则必须检查编译器的文档。 因此,您需要编写规则:

%.as: %.c ${INC_DIR}
${CC} ${CPPFLAGS} ${CFLAGS} -S -o $@ $<

(等(。 现在,当您将lib/GPIO/gpio.c编译为lib/GPIO/gpio.as时,make会将$@设置为lib/GPIO/gpio.as并调用编译器,使其创建lib/GPIO/gpio.as而不是gpio.as

但是您想将输出文件放在build子目录中。 既然你已经说服编译器在 make 告诉它的地方编写文件,你必须告诉 make 将输出放在哪里。

因此,首先,当您生成要创建的输出文件时,您必须使用正确的路径创建它们:

OBJS := $(SRCS:.c=.p1)

这会将lib/GPIO/gpio.c转换为lib/GPIO/gpio.p1这不是您想要的。 你需要这个:

OBJS := $(SRCS:%.c=build/%.p1)

现在,让知道你想构建build/lib/GPIO/gpio.p1。 但是现在您会收到一个错误,因为 make 不知道如何创建该文件。 您已经告诉它如何从%.c构建%.p1,但%必须是目标和先决条件之间的精确文本匹配,此处的目标%匹配build/lib/GPIO/gpio但没有build/lib/GPIO/gpio.c,因此规则不匹配。 您需要像这样重写规则:

build/%.p1: %.c ${INC_DIR}
${CC} ${CPPFLAGS} ${CFLAGS} --pass1 -o $@ $<

现在它应该可以工作了。 您可能还需要添加mkdir以确保目录存在:

build/%.p1: %.c ${INC_DIR}
@mkdir -p ${@D}
${CC} ${CPPFLAGS} ${CFLAGS} --pass1 -o $@ $<

相关内容

  • 没有找到相关文章

最新更新