Makefile:sedを正しく使用して変数を編集する方法

Makefile:sedを正しく使用して変数を編集する方法

すべてのソースファイルを収集して基本ファイル用にコンパイルするカスタムMakefileを作成しようとしています。まず、自分の名前を集めます。

# other sources to compile against (without extensions, separated by spaces)
DEPENDENT_FILES = greet farewell

.oその後、各単語に追加したいと思います。シェルでは、さまざまな方法でこれを実行できます。

echo '$DEPENDENT_FILES' | sed 's/\>/\.o/g' # but I know, it's UNIX dependant
# or ...
echo '$DEPENDENT_FILES' | sed 's/[^ ]*/&\.o/g'

greet.o farewell.oどちらも端末で結果を生成しますが、makeプロセスでは失敗します(結果として空の文字列が生成されます)。私はそれらを次のように書いています。

DEPENDENCIES := $(echo '$DEPENDENT_FILES' | sed 's/\>/\.o/g')
# or ...
DEPENDENCIES := $(echo '$DEPENDENT_FILES' | sed 's/[^ ]*/&\.o/g')
# but they result in
$(info DEPENDENCIES is $(DEPENDENCIES)) # "DEPENDENCIES is "

ここで私が何を間違っているのかわかりません。 Makefileのエコやパイプと関連があると疑われますが、把握することはできません。

私は他のアプローチを提案するよりも、sedおよびechoソリューションの仕事に関連する答えを好むことに注意してください。 Makefileのエコーとパイプに関する問題が発生したのは今回が初めてではなく、まだ私のアプローチにどのような問題があるのか​​わかりません。問題です。

答え1

その後、各単語の後に.oを追加したいと思います。

シェルによる往復は必要ありません。 Makeは助けるのに十分強力です。ファイル名の一般的な操作 このように。あなたの場合は、説明を必要としない名前の関数が必要です addsuffix

DEPENDENCIES = $(addsuffix .o, $(DEPENDENT_FILES))

これでa.o b.o c.o入力リストが表示されますa b c。より完全な例:

units = a b c

inc = $(addsuffix .h,$(units))
obj = $(addsuffix .o,$(units))

myprog: $(obj)
    gcc -o $@ $(obj)

header-bundle.h: $(inc)
    cat $< >$@

より複雑な交換が必要な場合は、さまざまな交換方法があります。一般的な文字列操作 しかし、十分であれば、ファイルの操作がより便利で謙虚な人が理解しやすくなると思います。

答え2

これらの構文は類似点が多いが非常に異なるため、非常に注意して使用する必要があることを認識する必要がありmakeますshell。しかも make は警告に非常に恥ずかしい。

コードmakeには2つの問題があります。

## bad code 
DEPENDENCIES := $(echo '$DEPENDENT_FILES' | sed 's/\>/\.o/g')
  • makeがその意味を理解する方法なので、GNU make名前の付いた組み込み関数はありません。echo l
  • 外部ユーティリティを実行する必要があるのは、gnu make組み込み$(shell ...)関数を呼び出すことです。
  • これで、makeコードを書く方法に隠された潜在的な問題がありますが、それは変数です$DEPENDENT_FILES。 makeはこれをmake変数$ Dに解析し、その後に文字列リテラルEPENDENT!が続きます。これは、make varsが括弧または中括弧で囲まれていない場合、文字が1つだけで、残りがリテラル文字列として扱われるためです。
  • evalが実行されていない限り、シェルvars veginの前には$$が付きます。

関連情報