首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >输入对象文件的Makefile食谱问题

输入对象文件的Makefile食谱问题
EN

Stack Overflow用户
提问于 2019-01-31 10:15:13
回答 1查看 46关注 0票数 0

我有一个makefile,我编辑了它,这样对象文件就应该转到一个单独的目录中。

我编辑了makefile,现在它正在做我想做的事情,但是在链接器阶段,它没有像预期的那样工作,因为我做了一些错误的事情。

我有一个sources文件和makefile,如下所示:

源文件

代码语言:javascript
运行
复制
TARGET = demo

SRC_DIR = modbus/ascii/ \
    modbus/functions/ \
    modbus/port/ \
    modbus/rtu/ \
    modbus/ \
    ./

INCLUDE_DIR =   modbus/include/ \
    modbus/port/ \
    modbus/rtu \
    modbus/ascii \
    ./

SOURCE =    modbus/ascii/mbascii.c \
    modbus/functions/mbfunccoils.c \
    modbus/functions/mbfuncdiag.c \
    modbus/functions/mbfuncdisc.c \
    modbus/functions/mbfuncholding.c \
    modbus/functions/mbfuncinput.c \
    modbus/functions/mbfuncother.c \
    modbus/functions/mbutils.c \
    modbus/port/port.c \
    modbus/port/portevent.c \
    modbus/port/portserial.c \
    modbus/port/porttimer.c \
    modbus/rtu/mbcrc.c \
    modbus/rtu/mbrtu.c \
    modbus/mb.c \
    demo.c \
    startup_LPC17xx.c \
    system_LPC17xx.c

Makefile

代码语言:javascript
运行
复制
include ./sources
ARCH = arm-none-eabi
BUILD_DIR := build/objs
# Tool definitions
CC      = $(ARCH)-gcc
LD      = $(ARCH)-gcc
AR      = $(ARCH)-ar
AS      = $(ARCH)-as
CP      = $(ARCH)-objcopy
OD      = $(ARCH)-objdump
SIZE    = $(ARCH)-size
RM      = rm
Q       = # @./quiet "$@"

# Flags
CFLAGS   = -W -Wall -O0 --std=gnu99 -fgnu89-inline -mcpu=cortex-m3 -mthumb 
CFLAGS  += -ffunction-sections -fdata-sections 
ASFLAGS  =
LDFLAGS  = -nostartfiles -specs=nosys.specs 
CPFLAGS  =
ODFLAGS  = -x --syms
PRFLAGS ?=

# Source files
LINKER_SCRIPT = LPC17xx.ld

OBJS   = $(SOURCE:.c=.o)
BUILD_OBJS := $(patsubst %,$(BUILD_DIR)/%,$(SOURCE:.c=.o))
OBJ_DIR := $(dir $(BUILD_OBJS))

INC_PARAMS = $(foreach d, $(INCLUDE_DIR), -I$d)

print-%  : ; @echo $* = $($*)

.PHONY: all size clean nuke

all: $(TARGET).bin $(TARGET).hex

isp: $(TARGET).bin
#   @./quiet $< cp $^ $(MBED_VOLUME)/

size: $(TARGET).elf
    @$(SIZE) $<

%.hex: %.elf
    $Q $(CP) $(CPFLAGS) -O ihex $< $*.hex

%.bin: %.elf
    $Q $(CP) $(CPFLAGS) -O binary $< $*.bin

$(TARGET).elf: $(OBJS)
    @touch $(@:.elf=.map)
    $Q $(LD) -Xlinker -Map $(@:.elf=.map) $(LDFLAGS) -T $(LINKER_SCRIPT) $(BUILD_DIR)/$^ -o $@ 
    $Q $(OD) $(ODFLAGS) $@ > $(@:.elf=.dump)
    @$(SIZE) $@

$(OBJS): %.o: %.c
    mkdir -p $(dir $(BUILD_OBJS))
    $Q $(CC) $(CFLAGS) $(INC_PARAMS) -c $< -o $(BUILD_DIR)/$@

.PHONY: clean
clean:  CRUFT=$(shell find . -name '*.o' -o -name '*.d')
clean:  ; rm -f $(CRUFT); rm -f *.elf *.hex *.bin *.dump *.map; rm -rf $(BUILD_DIR)/*
nuke: clean
    -rm -f *.hex *.bin *.dump *.map

这个问题是一致的:

代码语言:javascript
运行
复制
$Q $(LD) -Xlinker -Map $(@:.elf=.map) $(LDFLAGS) -T $(LINKER_SCRIPT) $(BUILD_DIR)/$^ -o $@  

其产出为:

代码语言:javascript
运行
复制
arm-none-eabi-gcc -Xlinker -Map demo.map -nostartfiles -specs=nosys.specs  -T LPC17xx.ld build/objs/modbus/ascii/mbascii.o modbus/functions/mbfunccoils.o modbus/functions/mbfuncdiag.o modbus/functions/mbfuncdisc.o modbus/functions/mbfuncholding.o modbus/functions/mbfuncinput.o modbus/functions/mbfuncother.o modbus/functions/mbutils.o modbus/port/port.o modbus/port/portevent.o modbus/port/portserial.o modbus/port/porttimer.o modbus/rtu/mbcrc.o modbus/rtu/mbrtu.o modbus/mb.o demo.o startup_LPC17xx.o system_LPC17xx.o -o demo.elf  

output命令只从build/objs下的正确目录中选择第一个对象文件。

Rest对象文件路径没有build/objs/

有人能帮我解决这个问题吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-31 19:46:20

你违反了“疯狂科学家”的第二条制作规则,引发了比你所知道的更多的问题。

看看这些规则(简化):

代码语言:javascript
运行
复制
$(TARGET).elf: $(OBJS)
    $(LD) $(BUILD_DIR)/$^ -o $@ 

$(OBJS): %.o: %.c
    $(CC) -c $< -o $(BUILD_DIR)/$@

假设构建目录为build/,对象文件为build/foo.o。第二个规则的目标是foo.o,但它实际上构建的是build/foo.o。同样,第一条规则声称foo.o是先决条件,但它实际上不使用foo.o,它使用build/foo.o --从某种意义上说,这两个错误相互抵消;成功地构建主目标。但是正如您所发现的,如果有多个对象文件,则会有问题,因为如果先决条件列表是foo.o bar.o,那么

代码语言:javascript
运行
复制
`$(BUILD_DIR)/$^`

扩展到

代码语言:javascript
运行
复制
build/foo.o bar.o

而且,即使build/foo.o存在并且是最新的,Make也会运行第二条规则,如果foo.o存在,则无法运行它。非虚假规则的目标应该是它构建的文件的名称,而非虚假的先决条件应该是与其存在相关的文件的名称:

代码语言:javascript
运行
复制
$(TARGET).elf: $(BUILD_OBJS)
    $(LD) $^ -o $@ 

$(BUILD_OBJS): $(BUILD_DIR)/%.o: %.c
    $(CC) -c $< -o $@
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54458220

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档