さて、私はこれに固執していて、何が間違っているのかわかりません。より複雑なメイクファイルですべてがうまく機能していましたが、突然「セパレータがありません」というエラーが発生しました。私はそれを非常に単純なシナリオに分離することができました:
define Push_dir
$(info ${1})
endef
define pop_dir
$(info ${1})
endef
define include_submake
$(call Push_dir,${1})
$(call pop_dir,${1})
endef
include test.mk
INITIAL_SUBMAKE:= includeme.mk
$(call include_submake,${INITIAL_SUBMAKE})
process:
@echo Processed...
そして出力:
C:\project>make -f Simple process
includeme.mk
includeme.mk
Simple:4: *** missing separator. Stop.
includeme.mk
は実際には存在しません。ここで何がうまくいかないのかわかりません。私はさまざまなことを試しました。 include_submakeの呼び出しをinfoで囲むと、次のようになります。
$(info $(call include_submake,${INITIAL_SUBMAKE}))
セパレーターがないというエラーはなくなりました。また、include_submake
定義で、関数の1つだけを呼び出すと、正常に機能します。さらに、関数をinclude_submake
ではなく直接呼び出すと、次のように機能します。
include test.mk
INITIAL_SUBMAKE:= includeme.mk
$(call Push_dir,${INITIAL_SUBMAKE})
$(call pop_dir,${INITIAL_SUBMAKE})
process:
@echo Processed...
C:\project>make -f Simple process
includeme.mk
includeme.mk
Processed...
ここで基本的なことを見落としているような気がします。ご協力いただきありがとうございます。
_missing separator
_エラーは、空の戻り値_include_submake
_が原因で発生します。これは、ケースでは単一の改行文字です。 Makeは、あるルールまたは別のディレクティブの一部であると想定されていない式で空白文字(つまり、スペースまたはタブ)を使用することのみを許可します。
昔ながらのMake変数の代入を使用して関数を書き直すと、エラーがなくなるはずです。
_Push_dir = \
$(info $1)
pop_dir = \
$(info $1)
include_submake = \
$(call Push_dir,$1) \
$(call pop_dir,$1)
_
define
vsプレーンな古い変数の割り当て最初のコメントからの質問への回答。個人的には、いくつかのケースでdefine
ディレクティブを使用したいと思います。
eval
関数での使用GNUマニュアルで提案するように、define
ディレクティブは eval
関数 と組み合わせて使用すると非常に便利です。マニュアルの例(強調は私のものです):
PROGRAMS = server client server_OBJS = server.o server_priv.o server_access.o server_LIBS = priv protocol client_OBJS = client.o client_api.o client_mem.o client_LIBS =プロトコル #この後のすべては一般的です 。PHONY:すべて すべて:$(PROGRAMS) pROGRAM_templateを定義する $(1):$$($(1)_OBJS)$$($(1)_LIBS:%=-l%) ALL_OBJS + = $$($(1)_OBJS ) エンデフ $(foreach prog、$(PROGRAMS)、$(eval $(call PROGRAM_template、$(prog)))) $(PROGRAMS): $(LINK.o)$ ^ $(LDLIBS)-o $ @ clean: rm -f $(ALL_OBJS)$(PROGRAMS)
逐語的変数は、GNU Makeからファイルを生成する場合に完全に適合します。たとえば、Makefileからの情報に基づいてヘッダーファイルを生成することを検討してください。
#引数: #1。ヘッダー識別子。header_templateを定義します /*このファイルはGNU Make $(MAKE_VERSION)。*/ #ifndef $(inclusion_guard)[.____によって生成されます。 ] #define $(inclusion_guard) $(foreach inc、$($ 1.includes)、 #include <$(inc).h>) /*他の何か... * / #endif/* $(inclusion_guard)*/ エンデフ#1。一意のヘッダー識別子。 inclusion_guard =\ __GEN_ $ 1_H #シェルエスケープ。 sh_quote =\ '$(subst'、 '"'" '、$ 1)' foo.includes:= bar baz HEADERS:= foo.h $(HEADERS):%。h: @printf "%s" $(call sh_quote、$(call header_template 、$(* F)))> $ @
私たちのプロジェクトでは、 Mybuild と呼ばれる独自のビルドシステムを使用し、GNU Make。以前の低レベルのハックの1つとして完全に実装されています。 Makeの組み込み言語の貧弱な構文を改善し、関数定義に拡張構文を使用できるようにする 特別なスクリプト を開発しました。スクリプト自体もMakeで記述されているため、一種のMakeでのメタプログラミング。
特に、次のような機能を使用できます。
$(assert ...)
や$(lambda ...)
などのカスタムマクロの定義$(eq s1,s2)
(文字列の等価性チェック)のような単純な関数のインライン化これは、拡張構文を使用して関数を作成する方法の例です。これは有効なMake関数になり、$(def_all)
の呼び出し後に通常どおり呼び出すことができることに注意してください。
#指定されたリストを逆にします。 #1。リスト #戻り値: #要素を逆順にしたリスト。リバースを定義する#空のリストから開始します。 $(fold、$ 1、 #新しい各要素($ 2)を に追加します。#前の計算の結果。$(ラムダ$ 2 $ 1)) エンデフ $(def_all)
これらの新機能を使用して、次のようないくつかの本当にクールなものを実装することができました(まあ、少なくともMake :-)の場合)
コード の任意の部分を自分のプロジェクトで自由に使用してください!
私は同じ問題に遭遇しました。 「タブ」を挿入し、「タブ」を削除し、念のため再挿入しました。同じエラーメッセージ。
しかし、私はこれらすべてをXCodem内で実行しましたが、驚いたことに、 '\ t'ではなく空白が挿入されました。別のエディターを使用すると、これらの「ファントム」エラーはなくなりました。
HTH.。