【问题标题】:Atmega8 - Compile and link C and Assembly-files with one MakefileAtmega8 - 使用一个 Makefile 编译和链接 C 和汇编文件
【发布时间】:2017-01-23 16:16:14
【问题描述】:

我正在玩 Atmega8 和 Assembly。 所以我想到了拥有一个 Makefile 会很好的点,它可以浏览文件夹,抓取每个 *.S、*.c 和 *.cpp 文件,链接并将它们编译为可闪存的二进制文件。 我使用 avr-toolchain 和 BootHID 来刷新二进制文件,但我认为最后一个无关紧要。

这就是我目前得到的:

CROSS   ?=/home/nico/Dokumente/avr8-gnu-toolchain/bin/avr-
CC      :=$(CROSS)gcc
CXX     :=$(CROSS)g++
LD      :=$(CROSS)g++
SIZE    :=$(CROSS)size
OBJCOPY :=$(CROSS)objcopy
OBJDUMP :=$(CROSS)objdump

BOOTHID = /home/nico/Dokumente/bootloadHID/commandline/bootloadHID

RM=rm -f

TARGET=a
MMCU?=atmega8
AVRDUDE_FLAGS?=

SOURCES=$(wildcard *.cpp) $(wildcard *.c) $(wildcard *.S)
INCLUDES=

#SETTINGS=settings.h

OBJECTS = $(patsubst %.cpp,%.o,$(patsubst %.c,%.o,$(patsubst %.S,%.o,$(SOURCES))))

CSTD?=c99
COPT=-O2 -fdata-sections -ffunction-sections
CFLAGS=-mmcu=$(MMCU) -std=$(CSTD) $(COPT) -Wall
CFLAGS+=$(addprefix -I,$(INCLUDES))
CFLAGS+=-include

CXXSTD?=c++98
CXXOPT=$(COPT) -fno-exceptions -fno-rtti
CXXFLAGS=-mmcu=$(MMCU) -std=$(CXXSTD) $(CXXOPT) -Wall
CXXFLAGS+=$(addprefix -I,$(INCLUDES))
CXXFLAGS+=-include

LDFLAGS=-mmcu=$(MMCU) -Wl,--gc-sections -Wl,-Map=$(TARGET).map,--cref

.PHONY: all avrdude flash
all: $(TARGET).hex $(TARGET).lst

$(TARGET).elf: $(OBJECTS)
    $
    $(LD) $(LDFLAGS) $^ -lm -o $@

$(TARGET).hex: $(TARGET).elf
    $(OBJCOPY) -O ihex -R .eeprom -R .fuse -R .lock -R .signature $< $@

$(TARGET).bin: $(TARGET).elf
    $(OBJCOPY) -O binary -R .eeprom -R .fuse -R .lock -R .signature $< $@

%.o: %.cpp
    $(CXX) -o $@ $(CXXFLAGS) -MMD -MP -MF $(@:%.o=%.d) $< -c

%.o: %.c
    $(CC) -o $@ $(CFLAGS) -MMD -MP -MF $(@:%.o=%.d) $< -c

%.o: %.S
    $(CC) -mmcu=$(MMCU) -c -o timing.o timing.S

$(TARGET).lst: $(TARGET).elf
    $(OBJDUMP) -h -S $< > $@

avrdude: $(TARGET).hex
    avrdude $(AVRDUDE_FLAGS) -e -m flash -i $<

flash: $(TARGET).hex
    $(BOOTHID) $<

clean:
    $(RM) $(OBJECTS) *.elf *.hex *.lst *.map *.d

如果我在文件夹中没有任何 *.S 文件,它就像一个魅力。

这行是硬编码的,只是为了调试。

 %.o: %.S
        $(CC) -mmcu=$(MMCU) -c -o timing.o timing.S

但是,一旦我将 Assemblyfile 与 c 文件一起放入目录中,我就会收到此错误:

$ make
/home/nico/Dokumente/avr8-gnu-toolchain/bin/avr-gcc -o lcd.o -mmcu=atmega8 -std=c99 -O2 -fdata-sections -ffunction-sections -Wall  -include -MMD -MP -MF lcd.d lcd.c -c
cc1: error: to generate dependencies you must specify either -M or -MM

这是我正在进行的一种集体项目。当我的小组伙伴通过 Visual Studio 编译代码时,一切都很好,所以我认为代码应该没问题。 但是我用的是linux,所以我在这里……

【问题讨论】:

  • 该命令甚至没有提到 asm 文件,如果它失败了,它也应该在没有 asm 规则的情况下失败。检查为什么没有。
  • 谷歌搜索,我发现“bugs.eclipse.org/bugs/show_bug.cgi?id=330249#c11
  • @Jester ,是的,如果没有 asm 规则,它也会失败。但是当我在我尝试编译的目录中使用没有 asm 文件的 Makefile 时,它​​会起作用。
  • 确保没有名称冲突。不同行为的原因是您使用通配符来收集您的SOURCESOBJECTS
  • 没有名称冲突。目录有4个文件:“lcd.c”、“lcd.h”、“main.c”和“timing.S”

标签: assembly makefile embedded avr avr-gcc


【解决方案1】:

错误信息很清楚:

cc1: error: to generate dependencies you must specify either -M or -MM

编译器希望你给它一个标志。您目前没有给它任何一个标志,正如我们从错误消息之前打印的命令中看到的那样。

要解决这个问题,您可以将这些标志之一添加到您的 Makefile。有很多地方可以添加标志,但对于这个来说,在您拥有-MMD 的任何地方之后添加它是最有意义的。

或者,您可以通过删除 -MMD 选项来完全禁用 GCC 依赖项生成。

您也可以咨询GCC documentation for these preprocessor options

【讨论】:

    【解决方案2】:

    好吧,真怪。

    不得不删除/注释掉这两行

    ...
    #CFLAGS+=-include
    ...
    #CXXFLAGS+=-include
    ...
    

    因为之前的编辑,我忘记了。

    我已经稍微编辑了 asm 规则:

    %.o: %.S
        $(CC) -mmcu=$(MMCU) -c -o $@ $<
    

    如果有一天有人需要,这里是完整且更正的 Makefile:

    CROSS   ?=/home/nico/Dokumente/avr8-gnu-toolchain/bin/avr-
    CC      :=$(CROSS)gcc
    CXX     :=$(CROSS)g++
    LD      :=$(CROSS)g++
    SIZE    :=$(CROSS)size
    OBJCOPY :=$(CROSS)objcopy
    OBJDUMP :=$(CROSS)objdump
    
    BOOTHID = /home/nico/Dokumente/bootloadHID/commandline/bootloadHID
    
    RM=rm -f
    
    TARGET=a
    MMCU?=atmega8
    AVRDUDE_FLAGS?=
    
    SOURCES=$(wildcard *.cpp) $(wildcard *.c) $(wildcard *.S)
    INCLUDES=
    
    OBJECTS = $(patsubst %.cpp,%.o,$(patsubst %.c,%.o,$(patsubst %.S,%.o,$(SOURCES))))
    
    CSTD?=c99
    COPT=-O2 -fdata-sections -ffunction-sections
    CFLAGS=-mmcu=$(MMCU) -std=$(CSTD) $(COPT) -Wall
    CFLAGS+=$(addprefix -I,$(INCLUDES))
    
    CXXSTD?=c++98
    CXXOPT=$(COPT) -fno-exceptions -fno-rtti
    CXXFLAGS=-mmcu=$(MMCU) -std=$(CXXSTD) $(CXXOPT) -Wall
    CXXFLAGS+=$(addprefix -I,$(INCLUDES))
    
    LDFLAGS=-mmcu=$(MMCU) -Wl,--gc-sections -Wl,-Map=$(TARGET).map,--cref
    
    
    .PHONY: all avrdude flash
    all: $(TARGET).hex $(TARGET).lst
    
    $(TARGET).elf: $(OBJECTS)
    
        $(LD) $(LDFLAGS) $^ -lm -o $@
    
    $(TARGET).hex: $(TARGET).elf
        $(OBJCOPY) -O ihex -R .eeprom -R .fuse -R .lock -R .signature $< $@
    
    $(TARGET).bin: $(TARGET).elf
        $(OBJCOPY) -O binary -R .eeprom -R .fuse -R .lock -R .signature $< $@
    
    %.o: %.cpp
        $(CXX) -o $@ $(CXXFLAGS) -MMD -MP -MF $(@:%.o=%.d) $< -c
    
    %.o: %.c
        $(CC) -o $@ $(CFLAGS) -MMD -MP -MF $(@:%.o=%.d) $< -c
    
    %.o: %.S
        $(CC) -mmcu=$(MMCU) -c -o $@ $<
    
    $(TARGET).lst: $(TARGET).elf
        $(OBJDUMP) -h -S $< > $@
    
    avrdude: $(TARGET).hex
        avrdude $(AVRDUDE_FLAGS) -e -m flash -i $<
    
    flash: $(TARGET).hex
        $(BOOTHID) $<
    
    clean:
        $(RM) $(OBJECTS) *.elf *.hex *.lst *.map *.d
    

    感谢您的帮助

    【讨论】:

      猜你喜欢
      • 2012-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-05
      • 2013-09-04
      • 2018-11-22
      • 1970-01-01
      相关资源
      最近更新 更多