【问题标题】:Makefile compile many programs with main function with one makefile errorMakefile 用 main 函数编译许多程序,但只有一个 makefile 错误
【发布时间】:2020-05-25 14:45:53
【问题描述】:

我正在尝试使用一个 Makefile 来编译许多 .c 文件。我已经写好了所有的规则,我想添加一条规则,上面写着:执行所有依赖 .c 文件的规则。

参考:Compile all C files in a directory into separate programs

PROGRAMS := copy.c sec_soft.c
PROGRAMS_NO_EX := $(basename $(PROGRAMS))
PROGRAMS_TO_CREATE := $(PROGRAMS_NO_EX).elf $(PROGRAMS_NO_EX).dump $(PROGRAMS_NO_EX).bin $(PROGRAMS_NO_EX).hex $(PROGRAMS_NO_EX).mem  $(PROGRAMS_NO_EX).coe

RISCV_OPTIONS = -march=rv32if -mabi=ilp32 -o  
RISCV_LINK = $(RISCV_GCC) $(CFLAGS) $< -o $@                            #produces .elf file!
RISCV_OBJDUMP = $(RISCV_PREFIX)objdump -D   $(DFLAGS)                       #produces a dump file to see the assembly code!
RISCV_OBJCOPY = $(RISCV_PREFIX)objcopy -O binary                        #produces a bin file!

ALL_RES = $(PROGRAMS:%.c=%.elf)

%.elf: %.c
    $(info Generating .elf file from files: $(PROGRAMS_NO_EX))
    $(RISCV_LINK)
    $(info Success!)
    $(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)
%.dump: %.elf
    $(info Copying assembly to dump file $(PROGRAMS_NO_EX).dump)
    @$(RISCV_OBJDUMP) $< > $@
    $(info Success!)
    $(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)
%.bin: %.elf
    $(info Generating bin file)
    @$(RISCV_OBJCOPY) $< $@
    $(info Success!)
    $(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)
%.hex: %.bin 
    $(info Generating hex file)
    echo cd $(SCRIPTDIR)
    $(info Running binary to hex >>>)
    python $(SCRIPTDIR)/bin2hex.py -a $(START_ADDRESS) -o $@ $<
    $(info Hex Generation Successful!)
    $(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)
%.mem: %.bin
    $(info Instantiating memory addresses...)
    head -c $$(( $(START_ADDRESS))) /dev/zero | cat - $< | xxd -g1 -c4 | awk '{print $$5$$4$$3$$2}' > $@
    $(info Memory instantiation Successful!)
    $(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)
%.coe: %.bin
    $(info Instantiating memory vector...)
    python $(SCRIPTDIR)/bin2coe.py $< -o $@
    $(info Memory vector instantiation Successful )
    $(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)    

all: $(ALL_RES);

但是这行 ALL_RES = $(PROGRAMS:%.c=%.elf) 并没有执行所有的规则。我希望在生成 .elf 文件后,下面的所有规则都会执行,但不会执行。

我是 Makefile 新手,如有错误请见谅。

提前谢谢你

【问题讨论】:

  • ALL_RES = ... 是一个变量定义,它不会运行任何东西。也许您应该将其添加为规则(单行内容为$(ALL_RES):)?
  • 您要执行所有规则,还是使用.c 执行所有规则。先决条件,还是什么?
  • @Beta 您好,感谢您的评论。是的,我想用 .c 先决条件执行所有规则,但下面回答很粗鲁!
  • @Someprogrammerdude 你好!谢谢您的回答。它确实运行,但只有 .elf 文件扩展名。 Raspy 在下面给出了答案!

标签: c gcc makefile riscv


【解决方案1】:

make 不会创建您没有要求的目标。您的all 目标只要求创建扩展名为.elf 的文件,仅此而已。如果你想构建所有其他的,你应该告诉make这样做。

应该更新要构建的目标的定义,因为它不能正确创建文件名。按原样编写,它仅将扩展连接到变量的末尾。自己看:

$ make -rp 2>&1 | grep PROGRAMS_TO_CREATE
PROGRAMS_TO_CREATE := copy sec_soft.elf copy sec_soft.dump copy sec_soft.bin copy sec_soft.hex copy sec_soft.mem  copy sec_soft.coe

这应该更新为适当的字符串操作,例如:

PROGRAMS_TO_CREATE := $(foreach program,$(PROGRAMS_NO_EX),$(addprefix $(program),.elf .dump .bin .hex .mem .coe))

这将生成正确的目标列表:

$ make -rp 2>&1 | grep PROGRAMS_TO_CREATE
PROGRAMS_TO_CREATE := copy.elf copy.dump copy.bin copy.hex copy.mem copy.coe sec_soft.elf sec_soft.dump sec_soft.bin sec_soft.hex sec_soft.mem sec_soft.coe

设置为目标all的依赖后:

all: $(PROGRAMS_TO_CREATE)

将导致正确的构建。

【讨论】:

  • 非常感谢它的工作。但我不明白你在这一行中所说的“它只将扩展名连接到变量的末尾。”。我对 Makefiles 非常陌生,并且仍在尝试了解执行的工作原理。 - 为什么我使用 foreach 语句? - 为什么我不能像 Stackoverflow 其他帖子的参考链接那样做?再次感谢您!
  • 另外你能告诉我如何只执行一次配置语句,然后让 Makefile 检查它是否更新?这是我尝试过的: FORCE,touch and if: CONFIGURATION := configure --prefix=$(LIBRARY_DIR) --with-arch=rv32if --with-abi=ilp32d configure: config.status touch configure config.status: cd $(LIBRARY_DIR) && $(CONFIGURATION);if [ -a $(LIBRARY_DIR)/config.status ];然后 cd $(LIBRARY_DIR) && $(CONFIGURATION);菲;
  • 我在答案中向您展示了:当您的 $(PROGRAMS_NO_EX) 包含 copy sec_soft 时,表达式 $(PROGRAMS_NO_EX).elf 只是扩展为 copy sec_soft.elf,而不是您可能期望的 copy.elf sec_soft.elf。跨度>
  • 至于引用的链接:它确实基于 .c 文件名创建了目标,这也是您在示例中所拥有的。问题是,在您的情况下,这不是唯一的最终目标。您没有一个最终目标,而是 .elf、.dump、.bin、.hex、.mem 和 .coe。所以你的ALL_RES 应该说$(PROGRAMS:%.c=%.elf) $(PROGRAMS:%.c=%.dump) $(PROGRAMS:%.c=%.bin) $(PROGRAMS:%.c=%.hex) $(PROGRAMS:%.c=%.mem) $(PROGRAMS:%.c=%.coe),这是我建议的另一个变体(带有$(foreach))。请记住,make 仅构建您请求的目标及其依赖项。
  • 我明白了。再次非常感谢!
猜你喜欢
  • 1970-01-01
  • 2013-03-10
  • 2011-08-22
  • 1970-01-01
  • 2018-04-23
  • 2017-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多