別のファイルの内容を読み取って、メイクファイルに変数を作成します


82

makefileからオンザフライで変数を作成するにはどうすればよいですか。その値は別のデータファイルの内容全体になります。

回答:


49

Makefileの変数を別のファイルの内容に設定したいと思います。

FILE=test.txt
VARIABLE=`cat $(FILE)`

target:
    echo $(VARIABLE)

3
実際、VARIABLE定義を何よりも優先することはできません。これは、all:ターゲットでいくつかのコマンドが実行されるまでPATH_TO_MY_DATA_FILEが存在しないためです。別の方法として、私が行ったことは、物事を2つのメイクファイルに分割し(サブメイクを作成)、サブメイクの先頭でVARIABLEを宣言したことです。これで、チャームのように機能します。
Srinath 2011

26
これは間違った答えです。の値は、シェルによってレシピでのみ展開されるVARIABLE文字列cat $(FILE)(引用符で囲まれています)です。のようにその値を出力してみてください$(info ${VARIABLE})
Maxim Egorushkin 2013

4
@MaximEgorushkinそれは間違いではありません。あなたはただVARIABLE約束として考えなければなりません。これは、の古いバージョンで動作する唯一のバージョンですmake:=$(shell ...)は両方ともGNU拡張機能です。
2015年

7
反対票を投じた。これはcat、ルールが実行されるたびに実行されます。これは通常意図されたものではなく、遅いので警告する必要があります。さらに、ファイルがパイプの場合、意図しない副作用が発生します。:=変数が置き換えられたときではなく、変数が定義されたときにルールが評価されないように、割り当てはwithである必要があります。置換値は$(shell cat $(FILE))catコマンドが後でレシピルールによってではなく、makeによってインプレースで実行されるようにする必要があります。
Christian Hujer 2017

2
@ antred、makeは、catも含む標準のUNIX / POSIXツールセットの一部です。インストールする場合は、他のすべての基本的なツールをインストールするのが普通であり、それが問題を引き起こす非常にまれな状況があります。cat複雑な代替ルールではなく依存することで、メイクファイルの理解がはるかに簡単になり、ほとんど移植性が高くなるか、場合によってはより移植性が高くなります。
マイケル

82

GNU makeを想定すると:

file := whatever.txt
variable := $(shell cat ${file})

4
@ceving標準のGNUmakeを使用します。Solarismakeは移植性のないアプリケーションです。
Maxim Egorushkin 2015年

8
Gnu makeは標準でも、solarismakeよりもポータブルでもありません。「人気」はあなたの言葉です。移植性と標準的なコンフォメーションを真剣に検討する場合は、posixを使用してください。
把友情留在无盐

3
この場合は「人気」を使用します。非GNUMakeは原始的すぎます。1990年代のオペレーティングシステムのサポートを継続することを目指している場合は、@ bb-generationの答えがおそらく必要なものです(ただし、多くの場合、問題が発生します)。他のすべての場合、GNU Makeは簡単に利用できるか、おそらくデフォルトであるため、それを利用してください。
ガス

1
GNU makeはどこでも実行できるので、他のどのmakeよりもはるかに移植性があります。「標準」は主観的であり、当然のことです。
行進

27

GNU makeバージョン4.2はファイル読み取り操作をサポートしているため、Maxim Egorushkinのすばらしい答えに関して、この問題を解決するためのオプションの方法があります。

FILE     := test.txt
variable :=$(file < $(FILE))

エラーを修正しました。変数名では大文字と小文字が区別されます。「foo」、「FOO」、および「Foo」という名前はすべて、異なる変数を参照しています。(gnu.org/software/make/manual/html_node/Using-Variables.html
ヤロスラフNikitenko

引用符も必要ありません。$(file <"$(FILE)")は "test.txt"を開こうとします。
キャグニー

16

catWindowsには存在しません。LinuxおよびWindowsで機能するソリューション:

cat := $(if $(filter $(OS),Windows_NT),type,cat)
variable := $(shell $(cat) filename)

説明:WindowsではOS、「Windows_NT」と等しくなるように定義された環境変数が常に存在するようです。このように、Windowsの場合はtypeコマンドが使用され、Windows以外の場合catは使用されます。



4

GNU makeを使用している場合、この効果を得る別の方法は、別のmakefileのmake「include」を使用することです。

Makefileから:

include "./MyFile.mak"

次の内容のファイル「MyFile.mak」を作成します。

FILE := "my file content"
FILE += "more content 1"
FILE += "more content 2"

これが動作するようには思えない、私が取得Makefile:1: "./MyFile.mak": No such file or directory
knocte

それはおそらくあなたが作るのどれGNUバージョンを使用していること....またはGNUのメイクの本当に古いバージョン...試してみてください。「-v作る」
ビル・ムーア

同梱または自作ではインストールされないように注意してください場合は、マックでメイクを使用して、make -v与えGNU Make 3.81
knocte

Makefileで誤ってTAB文字をSPACE文字に変換していないことを確認しますか?この点で、MakeはPythonとしてほとんど迷惑です。
ビル・ムーア

私は引用符を除去することによって、私のMac上での作業にこれを持って、例えば: include ./MyFile
チャーリー・トラン

3

プラットフォームが指定されていないため、Solarisでの動作は次のようになります。

VERSION:sh = cat VERSION

all:
        echo $(VERSION)

0

これMAKEは、fileディレクティブが使用できないバージョン3で機能するより移植性の高いソリューションです。欠点は、プロセスで一時ファイルを作成する必要があることです。

$(shell echo define my_variable > file.tmp)
$(shell cat my_file.txt >> file.tmp)
$(shell echo endef >> file.tmp)
include file.tmp

主なアイデアはdefine、複数行変数を宣言するために特別に設計されたディレクティブを使用することです。もちろん、shellMakefileで使用するためにファイルの内容を明示的に書き込むことができれば、一時ファイルの使用を避けることができます。

ファイルに$記号が含まれている場合、MAKE展開されるときmy_variable(または割り当てられるときは、で定義する:=)に変数/ディレクティブとして展開しようとすることに注意してください。それを避けたい場合は、ファイルの内容を含める前にそれらをエスケープする必要があります。たとえば、代わりにcatこれを行うことができます:

$(shell sed 's/\$$/$$$$/g' my_file.txt >> file.tmp)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.