1. ホーム
  2. if-statement

[解決済み] Makefileの中で条件がある場合、ターゲット内部で

2022-02-07 22:44:41

質問

いくつかのファイルを検索してコピーする(if-else条件)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構文とシェル構文をごっちゃにして、目まぐるしいばかりです。テストなしでここまで大きくしてはいけません。外から始めて、内へ向かって作業しましょう。

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 をビルドしてから、2 番目の 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 は2つの場所のどちらかに存在する可能性があります。これをきれいにする一番簡単な方法は vpath ディレクティブを使用します。

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

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