Makefile没有针对目标的规则

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Makefile没有针对目标的规则相关的知识,希望对你有一定的参考价值。

当有明确的定义时,请抱怨目标'build / libc / string / strlen.c'没有规则。奇怪的是,它成功地为'build / libc / libc.a'编译了除了一个依赖项之外的所有依赖项。我曾经或者至少试图禁用内置隐式规则和变量,以避免花费数小时调试同时拔出头发,但它似乎没有帮助,因为我完全迷失了。

Makefile文件:

.SUFFIXES:

MAKEFLAGS += -rR

STD = gnu11
CFLAGS = -O2 -g -ffreestanding -fbuiltin -Wall -Wno-div-by-zero -D__is_vos_kernel__ -Iinclude
LFLAGS = -O2 -g -ffreestanding -fbuiltin -Wall -Wextra
LIBC_FLAGS = -O2 -g -D__is_vos_libc__ -Iinclude
LIBK_FLAGS = -O2 -g -ffreestanding -fbuiltin -D__is_vos_libc__ -Iinclude -D__is_vos_kernel__

CC = i386-elf-gcc
LD = i386-elf-ld
AR = i386-elf-ar
AS = /usr/local/bin/nasm

SYSROOT = sysroot
BUILDDIR = builddir

SYSARG = --sysroot=sysroot -isystem=/usr/include

LIBC_OBJECTS = $(wildcard libc/*.c)
LIBC_HEADERS = $(wildcard libc/*.h)
LLIBC_HEADERS = $(wildcard sysroot/usr/include/*.h)

header:=$(shell find libc -type f -name "*.h")

prepare-dir:
    mkdir -p sysroot/usr/include sysroot/usr/lib build

sysroot/usr/include/%.h: libc/%.h prepare-dir
    cd libc; rsync -R $(<:libc/%=%) ../sysroot/usr/include

prepare-headers: $(addprefix sysroot/usr/include/, $(header:libc/%=%))
    @echo $^

prepare: prepare-dir prepare-headers

build/libc/%.o: libc/%.c prepare
    $(CC) $(SYSARG) -c $< -o $@ -std=$(STD) $(LIBC_FLAGS)

libc_objects = $(shell find libc -type f -name "*.c")
libco_pre = $(addprefix build/, $(libc_objects)))

build/libc/libc.a: $(libco_pre:.c=.o)
    $(AR) rcs $@ $^

clean:
    find . -type f -name "*.o" -delete
    find sysroot -type f -name "*" -delete
    # find sysroot -type d -name "*" -delete
    find build -type f -name "*" -delete
    # find build -type d -name "*" -delete

命令日志:

G16-MACBOOKPRO:VioletOS ghifari160$ make -rR build/libc/libc.a
mkdir -p sysroot/usr/include sysroot/usr/lib build
cd libc; rsync -R stdbool.h ../sysroot/usr/include
cd libc; rsync -R stdint.h ../sysroot/usr/include
cd libc; rsync -R stdlib.h ../sysroot/usr/include
cd libc; rsync -R string.h ../sysroot/usr/include
cd libc; rsync -R sys/cdefs.h ../sysroot/usr/include
sysroot/usr/include/stdbool.h sysroot/usr/include/stdint.h sysroot/usr/include/stdlib.h sysroot/usr/include/string.h sysroot/usr/include/sys/cdefs.h
i386-elf-gcc --sysroot=sysroot -isystem=/usr/include -c libc/stdlib/abort.c -o build/libc/stdlib/abort.o -std=gnu11 -O2 -g -D__is_vos_libc__ -Iinclude
i386-elf-gcc --sysroot=sysroot -isystem=/usr/include -c libc/string/malloc.c -o build/libc/string/malloc.o -std=gnu11 -O2 -g -D__is_vos_libc__ -Iinclude
i386-elf-gcc --sysroot=sysroot -isystem=/usr/include -c libc/string/memcmp.c -o build/libc/string/memcmp.o -std=gnu11 -O2 -g -D__is_vos_libc__ -Iinclude
i386-elf-gcc --sysroot=sysroot -isystem=/usr/include -c libc/string/memcpy.c -o build/libc/string/memcpy.o -std=gnu11 -O2 -g -D__is_vos_libc__ -Iinclude
i386-elf-gcc --sysroot=sysroot -isystem=/usr/include -c libc/string/memmove.c -o build/libc/string/memmove.o -std=gnu11 -O2 -g -D__is_vos_libc__ -Iinclude
i386-elf-gcc --sysroot=sysroot -isystem=/usr/include -c libc/string/memset.c -o build/libc/string/memset.o -std=gnu11 -O2 -g -D__is_vos_libc__ -Iinclude
i386-elf-gcc --sysroot=sysroot -isystem=/usr/include -c libc/string/strcat.c -o build/libc/string/strcat.o -std=gnu11 -O2 -g -D__is_vos_libc__ -Iinclude
make: *** No rule to make target `build/libc/string/strlen.c)', needed by `build/libc/libc.a'.  Stop.
答案

注意build/libc/string/strlen.c)末尾的右括号 - 它会阻止你的:.c=.o替换正常运行,所以make尝试在build目录中查找源文件,这当然不存在。

根本原因很可能是这一行有一个右括号太多了:

libco_pre = $(addprefix build/, $(libc_objects)))
                                      here -----^

它会在列表中的最后一个目标上添加一个右括号。这就是为什么所有以前的目标都已正确构建的原因。

以上是关于Makefile没有针对目标的规则的主要内容,如果未能解决你的问题,请参考以下文章

Recursive makefile 没有规则使目标“全部”。停止

gcc makefile错误:“没有规则来制作目标......”

Makefile总述②

makefile(06)_隐式规则

linux之Makefile 编写规则伪目标

makefile失败 - 隐式规则编译一个目标文件但不编译其余文件