85

いくつかのファイル (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

とにかく、それは「はい」、「ヘッダーをコピーしています」を2回出力し、sedが読み取れないと言って終了します/usr/include/asm-i386/unistd.h(もちろん、x64システムでは読み取れません)。makeif/else を理解していないだけで、代わりにすべてを 1 行ずつ実行していると言えます。

4

2 に答える 2

167

単純にシェル コマンドを使用できます。出力のエコーを抑制したい場合は、「@」記号を使用します。例えば:

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

各行の末尾;とat が必要であることに注意してください\

(これは、で終わらない限りmake、各行を別のコマンドとして解釈するためです)\

于 2015-06-11T07:07:33.720 に答える
88

ここにはいくつかの問題があるので、いつもの高レベルのアドバイスから始めます:小さくて単純なものから始めて、一度に少しずつ複雑さを加え、すべてのステップでテストし、機能しないコードには決して追加しないでください。(私は本当にそれをホットキーにするべきです。)

あなたはめまいがするような方法で 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

したがって、2番目の を呼び出す前に 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、2 つの場所のいずれかにある可能性があることです。これをクリーンアップする最も簡単な方法は、vpathディレクティブを使用することです。

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

unistd_32.h: unistd.h
    sed -e 's/__NR_/__NR32_/g' $< > $@
于 2013-04-12T18:13:20.833 に答える