Если условия в 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 и вместо этого запускает все по строкам.

Ответ 1

Здесь есть несколько проблем, поэтому я начну с моего обычного совета на высоком уровне: Начните с малого и просто, добавьте немного сложности за раз, испытайте на каждом шагу и никогда не добавляйте к коду, который не работает "Я работаю. (я действительно должен иметь эту горячую клавишу.)

Вы смешиваете синтаксис синтаксиса и синтаксиса оболочки таким образом, что это просто головокружительно. Вы никогда не должны позволять этому делать это без тестирования. Позвольте начать со стороны и работать внутри.

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

Итак, вы хотите, чтобы 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

Теперь для построения 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.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' $< > [email protected]

Ответ 2

Вы можете просто использовать команды оболочки. Если вы хотите подавить эхо вывода, используйте знак "@". Например:

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

Обратите внимание, что закрытие ";" и "\" необходимы.