4

Makefile の一般的なビルド テンプレートを作成しようとしています。これは、eval ドキュメントで説明されているようなものです。

GNU Make 3.80 で既知のバグに遭遇しました。$(eval) が 193 文字を超える行を評価すると、Make は「Virtual Memory Exhausted」エラーでクラッシュします。

問題を引き起こすコードは次のようになります。

SRC_DIR = ./src/

PROG_NAME = test

define PROGRAM_template
  $(1)_SRC_DIR = $$(SRC_DIR)$(1)/
  $(1)_SRC_FILES = $$(wildcard $$($(1)_SRC_DIR)*.c)
  $(1)_OBJ_FILES = $$($(1)_SRC_FILES):.c=.o)

  $$($(1)_OBJ_FILES) : $$($(1)_SRC_FILES) # This is the problem line
endef

$(eval $(call PROGRAM_template,$(PROG_NAME)))

この Makefile を実行すると、

gmake: *** virtual memory exhausted.  Stop.

予想される出力は、./src/test/ 内のすべての .c ファイルが (暗黙の規則によって) .o ファイルにコンパイルされることです。

問題は、$$($(1)_SRC_FILES) と $$($(1)_OBJ_FILES) が一緒になって 193 文字を超えることです (十分なソース ファイルがある場合)。

.c ファイルが 2 つしかないディレクトリで make ファイルを実行しようとしましたが、正常に動作しました。エラーが発生するのは、SRC ディレクトリに多数の .c ファイルがある場合のみです。

GNU Make 3.81 でこのバグが修正されていることは知っています。残念ながら、作業中のシステムに新しいバージョンをインストールする権限や能力がありません。私は3.80で立ち往生しています。

それで、何か回避策はありますか?$$($(1)_SRC_FILES) を分割して、eval 内で各依存関係を個別に宣言することはできますか?

4

2 に答える 2

5

笑ハック

ifneq (3.81,$(shell (echo $(MAKE_VERSION); echo 3.81) | sort | head -n1))

make-3.81/make:
        wget -nc http://ftp.gnu.org/pub/gnu/make/make-3.81.tar.gz
        gzip -cd make-3.81.tar.gz | tar xvf -
        cd make-3.81 && ./configure --prefix=$$(pwd)
        $(MAKE) -C make-3.81 make

%: make-3.81/make
        make-3.81/make $@

else

# rest of your makefile

endif

真剣に、3.81 のインストールを妨げるものは何もないでしょう。たとえそれがローカルにあるだけであってもです。

于 2010-03-11T21:05:12.567 に答える
3

おそらく誰もこれをもう必要としませんが、 を賢くinclude使えばこの種の制限を克服できると思います。

define PROGRAM_template次のようなものに置き換えます。

define PROGRAM_template
__template_arg := $(1)
include PROGRAM_template.mk
endef

PROGRAM_template.mkテンプレート マクロのコアを実装するために作成します。

$(__template_arg)_SRC_DIR = $(SRC_DIR)$(__template_arg)/
$(__template_arg)_SRC_FILES = $(wildcard $($(__template_arg)_SRC_DIR)*.c)
$(__template_arg)_OBJ_FILES = $($(__template_arg)_SRC_FILES:.c=.o)

$($(__template_arg)_OBJ_FILES) : $($(__template_arg)_SRC_FILES)
__template_arg :=

もちろん、これは少し醜いです (技術的にはマクロに引数を渡すためにグローバル変数を使用します)。私は最初の答えの方が好きです... :-)

于 2012-08-08T03:39:33.863 に答える