デバッグ方法
このパートでは、一般的なデバッグ手法と問題について説明します。最終的に、デバッグは、特定の状況で機能するすべてのものの寄せ集めです。これらのメソッドは私のために機能し、最も単純なmakefileで問題が発生した場合でもそれらに依存する必要があります。多分彼らもあなたを助けるでしょう。
make
3.80の非常に厄介なバグの1つは、makefileのエラーメッセージでmake
、行番号と通常は行番号が正しくありませんでした。インポートされたファイル、複数行の変数の割り当て、またはユーザーマクロが原因で、この問題が発生する理由をわざわざ調査していません。通常、make
必要以上の行番号を指定します。複雑なmakefileでは、番号が20行一致しないことがあります。
多くの場合、変数の値を確認する最も簡単な方法は、ターゲットの実行中に変数を印刷することです。ヘルプを使用して印刷するのは簡単ですがwarning
、長期的には、debug
変数を出力するための共通のターゲットを追加することで、多くの時間を節約できます。ターゲットコードの例を次に示しますdebug
。
debug: $(for v,$(V), \ $(warning $v = $($v)))
これを使用するには、コマンドラインに出力する必要のある変数の名前をリストし、debug
ターゲットをアセンブルする必要があります。
$ make V="USERNAME SHELL" debug makefile:2: USERNAME = Owner makefile:2: SHELL = /bin/sh.exe make: debug is up to date.
あなたが本当にすべてを魔法のように行うなら、あなたはMAKECMDGOALS
変数への割り当てを避けるために変数を使うことができますV
:
debug: $(for v,$(V) $(MAKECMDGOALS), \ $(if $(filter debug,$v),,$(warning $v = $($v))))
これで、コマンドラインに変数をリストするだけで変数を表示できます。ただし、make
変数を更新できないことに関する警告(ターゲットとして指定されているため)は混乱を招く可能性があるため、この方法はお勧めしません。
$ make debug PATH SHELL makefile:2: USERNAME = Owner makefile:2: SHELL = /bin/sh.exe make: debug is up to date. make: *** No rule to make target USERNAME. Stop.
make
, shell
. , , , . — :
DATE := $(shell date +%F) OUTPUT_DIR = out-$(DATE) make-directories := $(shell [ -d $(OUTPUT_DIR) ] || mkdir -p $(OUTPUT_DIR)) all: ;
sh
, :
$ make SHELL="sh -x" + date +%F + '[' -d out-2004-05-11 ']' + mkdir -p out-2004-05-11
, .
, , :
FIND_TOOL = $(firstword $(wildcard $(addsuffix /$(1).exe,$(TOOLPATH))))
. :
$(warning $(TOOLPATH)) $(warning $(addsuffix /$(1).exe,$(TOOLPATH))) $(warning $(wildcard $(addsuffix /$(1).exe,$(TOOLPATH))))
, ( ) .
make
make
. . , , make
, , . .
make
:
makefile:n: *** message. Stop
:
make:n: *** message. Stop.
makefile — . — , , , , , .
, make
, , makefile . , - , - . , — . , make
.
: , , .
make
:
foo: for f in $SOURCES; \ do \ … \ done
, make
$S
, OURCES
f
. , f
, :
OURCES: No such file or directory
. — .
missing separator
:
makefile:2:missing separator. Stop.
( GNU make — .):
makefile:2:missing separator (did you mean TAB instead of 8 spaces?). Stop.
make
, :, =, . , - .
commands commence before first target
makefile, ( ). make
, , , , make
.
unterminated variable reference
, . , . make
Lisp! , , Emacs.
: , , , .
" ", .
:
bash: foo: command not found
, foo
. , PATH
. , PATH
, .profile (Bourne shell), .bashrc (bash) .cshrc (C shell). , PATH
makefile, PATH
make
.
, . , make
:
$ make touch /foo/bar touch: creating /foo/bar: No such file or directory make: *** [all] Error 1
touch
, . — make
. makefile , . , , make
.
, @
. .
make
, make
.
No Rule to Make Target
:
make: *** No rule to make target XXX. Stop.
:
make: *** No rule to make target XXX, needed by YYY. Stop.
, make
XXX, make
. make
.
:
- makefile . .
- makefile — .
make
. makefile , .make
. ,
make
- , ,make
. ,make
. — VCS. ,make
- , - . , .
Overriding Commands for Target
make
( «::» , ). ,make
:
makefile:5: warning: overriding commands for target foo
:
makefile:2: warning: ignoring old commands for target foo
, ; .
makefile , . , , .
, :
# Create a jar file. $(jar_file): $(JAR) $(JARFLAGS) -f $@ $^
makefile . makefile:
# Set the target for creating the jar and add prerequisites jar_file = parser.jar $(jar_file): $(class_files)
このようなmakefileに誤ってコマンドスクリプトを追加すると、make
オーバーライド警告が発行されます。