【问题标题】:Create intermediate files in build directory from makefile从 makefile 在 build 目录中创建中间文件
【发布时间】:2019-12-31 16:00:28
【问题描述】:

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

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

Project/build/lib/GPIO

makefile 正在项目目录本身中生成中间文件。实际上 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} $@ $<

【问题讨论】:

    标签: makefile xc8


    【解决方案1】:

    我要说的第一件事是这个答案取决于您使用 GNU make。你不能肯定地说你是,但由于你使用的是模式规则,我会假设是这样。请注意,标准 POSIX make 无法实现您想要做的事情(除非您想为每个要构建的目标写出明确的规则)。

    你需要两件事:

    1. 告诉编译器你想做什么
    2. 告诉make你想做的事

    对于#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)
    

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

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

    现在应该可以了。您可能还想添加 mkdir 以确保目录存在:

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

    【讨论】:

    • 在 MPLABX 调试中是否有任何可用于 xc8 编译器的命令行调试功能?
    • 我不明白这个问题:我对xc8 编译器或MPLABX debug 是什么一无所知。但是,这似乎与您询问的问题完全正交,因此您应该在 StackOverflow 中创建一个全新的问题,其中包含您想知道的全部详细信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多