linux - .c 文件旁边带有 .s 文件的 makefile

标签 linux makefile

我有一个裸机项目,其中包含 .s 文件和 .c 文件。如何编写 makefile 将 .s 文件的编译与 .c 文件分开?这些文件位于程序的子文件夹(源、包含、启动)中。

我本来就想做这样的事情。这个好吗?那么如何将对象链接到可执行文件中?

SHELL := /bin/bash
ROOT := $(shell pwd)
VPATH := $(ROOT)/source:/$(ROOT)/startup:$(ROOT)/include
EXE := exe
OBJECTS_GCC := $(patsubst %.c,%.o,$(wildcard *.c))
OBJECTS_AS := $(patsubst %.s,%.o,$(wildcard *.s))
AS := arm-none-eabi-as -mcpu=arm926ej-s -Wall
GCC := arm-none-eabi-gcc -mcpu=arm926ej-s -Wall
LD := arm-none-eabi-ld -T test.ld -o $(EXE)

all: $(EXE)
$(EXE): startups sources

startups: $(OBJECTS_AS)
    $(AS) $(OBJECTS_AS)

sources: $(OBJECTS_GCC)
    $(GCC) $(OBJECTS_GCC)

我很难找到任何包含 .s 文件和 .c 文件的示例。

问候。


这是最新版本的 makefile,其中未找到 header.h:

SHELL := /bin/bash
ROOT := $(shell pwd)
INC := $(ROOT)/inc
SRC := $(ROOT)/src
STR := $(ROOT)/str
EXE := exe
AS := arm-none-eabi-as -mcpu=arm926ej-s -c -Wall -I $(INC) -I$(SRC) -I $(STR)
GCC := arm-none-eabi-gcc -mcpu=arm926ej-s -c -Wall -I $(INC) -I$(SRC) -I $(STR)
LDSCRIPT := test.ld
LD := arm-none-eabi-ld -T $(LDSCRIPT)
HEADERS := $(notdir $(wildcard $(INC)/*.h))
SOURCES_GCC := $(notdir $(wildcard $(SRC)/*.c))
SOURCES_AS := $(notdir $(wildcard $(STR)/*.s))
OBJECTS_GCC := $(SOURCES_GCC:.c=.o)
OBJECTS_AS := $(SOURCES_AS:.s=.o)
VPATH := $(STR):$(SRC):$(INC)

all : $(EXE)
    @echo konec postopka: izvrsljiv program po imenu $(EXE) se nahaja v mapi $(ROOT)

$(EXE) : $(OBJECTS_AS) $(OBJECTS_GCC)
    @echo objekti so: $(OBJECTS_AS) $(OBJECTS_GCC)
    @echo headerji so: $(HEADERS)
    @echo linkanje objektov v izvrsljiv program...
    $(LD) -o $@ $^

%.o : %.s %.h
    @echo prevajanje ASSEMBLY izvornih datotek...
    $(AS) -o $@  $<

%.o : %.c %.h
    @echo prevajanje C izvornih datotek...
    $(GCC) -o $@ $<

.PHONY : clean
clean :
    @echo brisanje objektov
    rm *.o
    @echo brisanje izvrsljivega programa
    rm $(EXE)

最佳答案

考虑一下如果没有 make 您会发出哪些命令。你会采取什么步骤?您首先创建哪些文件?文件在创建之前如何依赖于其他文件的存在?
一旦您对此有了清晰的认识,就可以编写模仿这些命令的 make 规则,但要包含 make 变量。

如果你掌握了这一点,那么你可以通过使用隐式规则、自动变量等来增强你的 makefile,但首先要保持简单,直到你掌握如何 make有效。

几点:

  • 我认为通配符函数不会以这种方式获取任何文件名。它只在当前目录中查找,不使用VPATH在其他目录中搜索。
  • 您使用 gcc 将对象作为输入。这样它将(尝试)创建一个可执行文件。
  • 您没有创建目标文件的规则。如果您依赖 make 的内置隐式规则或模式规则,这可能没问题,但它不会使用您想要使用的 gcc 版本及其关联标志。您必须设置一些其他变量才能使其正常工作(例如 CCCFLAGS 等)。
  • 您已经定义了LD,但从未使用过它。在配方中使用它来创建可执行文件。

我想你应该有更多类似这样的东西:

all: $(EXE)

$(EXE): $(OBJECTS_AS) $(OBJECTS_GCC)
    $(LD) $^

%.o: %.s
    $(AS) $<

%.o: %.c
    $(GCC) -c $<

关于linux - .c 文件旁边带有 .s 文件的 makefile,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5592486/

相关文章:

c++ - OpenCV 使用 CodeBlocks 在 Linux 中编译 Eigenface.cpp

Linux (Ubuntu) ioctl KDGETLED/KDGKBLED 始终为 0

makefile - 制作更好的 Makefile

c++ - 无法在 Windows 命令行中编译任何 Qt 项目,只能在 Qt Creator 中编译

Makefile 模式规则不起作用

linux - BZIP2 压缩文件滞后

linux - read() 会在 select() 之后阻塞吗?

linux - 使用管道和撇号时如何将 bash 命令的输出捕获到变量中?

linux - 我的 Makefile 中的 Bash 命令 ID 不起作用

makefile - 在Makefile中设置环境变量时@前缀