If statement 如果生成文件中存在条件,则在目标内部

If statement 如果生成文件中存在条件,则在目标内部,if-statement,makefile,target,If Statement,Makefile,Target,我正在尝试设置一个Makefile,它将搜索和复制一些文件(如果有其他条件),但我无法找出它到底出了什么问题?(我很确定这是因为空格/制表符组合写错了位置)。 我能得到一些帮助吗 以下是我目前拥有的: obj-m = linuxmon.o KDIR = /lib/modules/$(shell uname -r)/build UNAME := $(shell uname -m) all: $(info Checking if custom header is needed)

我正在尝试设置一个Makefile,它将搜索和复制一些文件(如果有其他条件),但我无法找出它到底出了什么问题?(我很确定这是因为空格/制表符组合写错了位置)。 我能得到一些帮助吗

以下是我目前拥有的:

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
无论如何,它会打印两次“Yes”,“Copying header”,然后它会停止说sed不能读取
/usr/include/asm-i386/unistd.h
(当然它不能读取,因为我在x64系统上)。
我可以说,
make
只是不理解if/else,而是一行一行地运行所有东西。

这里有几个问题,所以我将从我通常的高级建议开始:从小处开始,简单一点,一次增加一点复杂性,每一步都进行测试,永远不要添加不起作用的代码。(我真的应该把那个火辣辣的家伙弄到手。)

您将Make语法和shell语法混合在一起,这让人眼花缭乱。你不应该让它在没有测试的情况下变得这么大。让我们从外部开始,向内工作

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
因此,在调用第二个
make
之前,您需要构建unistd_32.h(可能),您可以将其作为先决条件。因为你只想在特定情况下这样做,你可以把它放在一个条件中:

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
现在,对于建筑
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
您正在尝试从
unistd_32.h
构建
unistd.h
;唯一的技巧是
unistd_32.h
可以位于两个位置中的任何一个。清除此问题的最简单方法是使用
vpath
指令:

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

unistd_32.h: unistd.h
    sed -e 's/__NR_/__NR32_/g' $< > $@
vpath unistd.h/usr/include/asm/usr/include/asm-i386
unistd_32.h:unistd.h
sed-e's/\uuuunr\uuuuunr32\uuuu/g'$<>$@

您可以简单地使用shell命令。如果要抑制输出回声,请使用“@”符号。例如:

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

请注意,结尾“;”和“\”是必需的。

谢谢,但我缺少2个if。make会自动完成吗?是的。如果两个头都不存在,Make会抱怨它不知道如何构建
unistd_32.h
。好吧,这真的让它更简单了。还有一件事,我可以打印一条错误消息,而不是抱怨不知道如何构建它吗?哦,我刚刚试过,但它不起作用。这就是我所拥有的:但上面说线路上缺少一个分隔符14@alexandernst:1)是的,您可以让Make打印错误消息,但您是否关心其他影响(例如中止生成、返回非零值)?2) Make规则中的每个命令都必须以一个选项卡开头。简单回答我的实际问题。这在Windows上不起作用。答案是使用Make
ifeq
ifneq
@s.ouchene。无论如何,你不应该在windows上使用Make。Make是为Unix和Linux开发的。使用跨平台构建系统,如cmake