如果条件在Makefile中,则在目标内

ale*_*nst 41 if-statement makefile target

我正在尝试设置一个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
Run Code Online (Sandbox Code Playgroud)

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

Ome*_*gan 75

您只需使用shell命令即可.如果要抑制回显输出,请使用"@"符号.例如:

clean:
    @if [ "test" = "test" ]; then\
        echo "Hello world";\
    fi
Run Code Online (Sandbox Code Playgroud)

注意结束";" 和"\"是必要的.

  • 简单回答我所遇到的实际问题。 (2认同)
  • 这在 Windows 上不起作用。答案是使用 Make `ifeq` 或 `ifneq`。 (2认同)
  • @s.ouchene 无论如何,你不应该在 Windows 上使用 make 。Make 是为 Unix 和 Linux 设计的。使用跨平台构建系统,例如 cmake (2认同)
  • @caelras 题外话,但澄清一下:Make 可能首先是在 Unix 世界中开发的,但只要您使用与 Windows 兼容的 make 或可以运行它的环境,就可以在 Windows 中使用。有几种“make”方言。此处引用的 GNU Make 是类 Unix 操作系统中最流行的,并且经常与自动工具一起使用。如果进行一些工作,它也可以在 Windows 下运行,例如在 Cygwin 下。CMake 完全是另一头野兽;这是一个不同的构建管理器。在 C++ 世界中很流行,但不仅可以在 Windows 下使用,还可以在类 Unix 操作系统中使用。 (2认同)

Bet*_*eta 58

这里有几个问题,所以我将从我通常的高级建议开始:开始小而简单,一次添加一点复杂性,在每一步测试,并且永远不会添加到不起作用的代码.(我真的应该热键.)

您正在以令人眼花缭乱的方式混合使用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
Run Code Online (Sandbox Code Playgroud)

所以你想在调用第二个之前建立unistd_32.h(也许)make,你可以把它作为先决条件.而且因为你只想在某种情况下,你可以把它放在一个条件:

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
Run Code Online (Sandbox Code Playgroud)

现在建设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
Run Code Online (Sandbox Code Playgroud)

你正试图建立unistd.h起来unistd_32.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' $< > $@
Run Code Online (Sandbox Code Playgroud)