如果 Makefile 中的条件在目标中

我正在尝试设置一个 Makefile,它将搜索和复制一些文件(if-else 条件) ,我不能找出它到底出了什么问题?(我很确定这是因为空格/制表符的组合写错了地方)。 能帮帮我吗?

以下是我目前拥有的:

obj-m = linuxmon.o


KDIR = /lib/modules/$(shell uname -r)/build
UNAME := $(shell uname -m)


all:


$(info Checking if custom header is needed)
ifeq ($(UNAME), x86_64)
$(info Yes)
F1_EXISTS=$(shell [ -e /usr/include/asm/unistd_32.h ] && echo 1 || echo 0 )
ifeq ($(F1_EXISTS), 1)
$(info Copying custom header)
$(shell sed -e 's/__NR_/__NR32_/g' /usr/include/asm/unistd_32.h > unistd_32.h)
else
F2_EXISTS=$(shell [[ -e /usr/include/asm-i386/unistd.h ]] && echo 1 || echo 0 )
ifeq ($(F2_EXISTS), 1)
$(info Copying custom header)
$(shell sed -e 's/__NR_/__NR32_/g' /usr/include/asm-i386/unistd.h > unistd_32.h)
else
$(error asm/unistd_32.h and asm-386/unistd.h does not exist)
endif
endif
$(info No)
endif


@make -C $(KDIR) M=$(PWD) modules


clean:
make -C $(KDIR) M=$(PWD) clean
rm unistd_32.h

无论如何,这将打印“是”,“复制头”两次,然后它将停止说 sed 不能读取 /usr/include/asm-i386/unistd.h(当然它不能读取,因为我在 x64系统上)。 我可以说 make只是不理解 if/else,而是逐行运行所有内容。

273438 次浏览

There are several problems here, so I'll start with my usual high-level advice: Start small and simple, add complexity a little at a time, test at every step, and never add to code that doesn't work. (I really ought to have that hotkeyed.)

You're mixing Make syntax and shell syntax in a way that is just dizzying. You should never let it get this big without testing. Let's start from the outside and work inward.

UNAME := $(shell uname -m)


all:
$(info Checking if custom header is needed)
ifeq ($(UNAME), x86_64)
... do some things to build unistd_32.h
endif


@make -C $(KDIR) M=$(PWD) modules

So you want unistd_32.h built (maybe) before you invoke the second make, you can make it a prerequisite. And since you want that only in a certain case, you can put it in a conditional:

ifeq ($(UNAME), x86_64)
all: unistd_32.h
endif


all:
@make -C $(KDIR) M=$(PWD) modules


unistd_32.h:
... do some things to build unistd_32.h

Now for building unistd_32.h:

F1_EXISTS=$(shell [ -e /usr/include/asm/unistd_32.h ] && echo 1 || echo 0 )
ifeq ($(F1_EXISTS), 1)
$(info Copying custom header)
$(shell sed -e 's/__NR_/__NR32_/g' /usr/include/asm/unistd_32.h > unistd_32.h)
else
F2_EXISTS=$(shell [[ -e /usr/include/asm-i386/unistd.h ]] && echo 1 || echo 0 )
ifeq ($(F2_EXISTS), 1)
$(info Copying custom header)
$(shell sed -e 's/__NR_/__NR32_/g' /usr/include/asm-i386/unistd.h > unistd_32.h)
else
$(error asm/unistd_32.h and asm-386/unistd.h does not exist)
endif
endif

You are trying to build unistd.h from unistd_32.h; the only trick is that unistd_32.h could be in either of two places. The simplest way to clean this up is to use a vpath directive:

vpath unistd.h /usr/include/asm /usr/include/asm-i386


unistd_32.h: unistd.h
sed -e 's/__NR_/__NR32_/g' $< > $@

You can simply use shell commands. If you want to suppress echoing the output, use the "@" sign. For example:

clean:
@if [ "test" = "test" ]; then\
echo "Hello world";\
fi

Note that the closing ; and \ at each line are necessary

(This is because make interpret each line as a seperate command unless it ends with \)