2016-10-23 7 views
0

私はGNU makeのプロジェクトを持っています。場合によってはmake allを実行するとビルドされますが、そのあとでデバッグシンボルファイルが再度作成され、となることがあります。時にはうまく動作し、Nothing to be done for 'all'という報告があります。Makefileはコマンドのようにランダムに実行します

[[email protected] kernel32]$ make clean 
make -C boot clean 
make[1]: Entering directory '/home/cad/Desktop/kernel/kernel32/boot' 
rm -f main.o boot.o floppy_errs.o install_ints.o drivers/i8259A.o drivers/i8042o drivers/vga.o *.ld.m4 
make[1]: Leaving directory '/home/cad/Desktop/kernel/kernel32/boot' 
make -C kernel clean 
make[1]: Entering directory '/home/cad/Desktop/kernel/kernel32/kernel' 
make[1]: Nothing to be done for 'clean'. 
make[1]: Leaving directory '/home/cad/Desktop/kernel/kernel32/kernel' 
rm -f *.out *.img *.sym 

[[email protected] kernel32]$ make all 
make -C boot all 
make[1]: Entering directory '/home/cad/Desktop/kernel/kernel32/boot' 
m4 ../m4/global.m4 m4/boot.m4 m4/asm.m4 ../m4/asm.m4 main.S | \ 
as -o main.o --32 -g 
m4 ../m4/global.m4 m4/boot.m4 m4/asm.m4 ../m4/asm.m4 boot.S | \ 
as -o boot.o --32 -g 
m4 ../m4/global.m4 m4/boot.m4 m4/asm.m4 ../m4/asm.m4 floppy_errs.S | \ 
as -o floppy_errs.o --32 -g 
m4 ../m4/global.m4 m4/boot.m4 m4/asm.m4 ../m4/asm.m4 install_ints.S | \ 
as -o install_ints.o --32 -g 
m4 ../m4/global.m4 m4/boot.m4 m4/asm.m4 ../m4/asm.m4 drivers/i8259A.S | \ 
as -o drivers/i8259A.o --32 -g 
m4 ../m4/global.m4 m4/boot.m4 m4/asm.m4 ../m4/asm.m4 drivers/i8042.S | \ 
as -o drivers/i8042.o --32 -g 
m4 ../m4/global.m4 m4/boot.m4 m4/asm.m4 ../m4/asm.m4 drivers/vga.S | \ 
as -o drivers/vga.o --32 -g 
m4 ../m4/global.m4 m4/boot.m4 boot.ld > boot.ld.m4 
ld -T boot.ld.m4 main.o boot.o floppy_errs.o install_ints.o drivers/i8259A.o drvers/i8042.o drivers/vga.o -melf_i386 
make[1]: Leaving directory '/home/cad/Desktop/kernel/kernel32/boot' 
objcopy --only-keep-debug boot.out boot.sym 
objcopy --strip-debug --strip-unneeded boot.out 
objcopy -O binary boot.out boot.img 

[[email protected] kernel32]$ make all 
make: Nothing to be done for 'all'. 

を奇妙な仕事:期待どおりに動作し

[[email protected] kernel32]$ make clean 
make -C boot clean 
make[1]: Entering directory '/home/cad/Desktop/kernel/kernel32/boot' 
rm -f main.o boot.o floppy_errs.o install_ints.o drivers/i8259A.o drivers/i8042o drivers/vga.o *.ld.m4 
make[1]: Leaving directory '/home/cad/Desktop/kernel/kernel32/boot' 
make -C kernel clean 
make[1]: Entering directory '/home/cad/Desktop/kernel/kernel32/kernel' 
make[1]: Nothing to be done for 'clean'. 
make[1]: Leaving directory '/home/cad/Desktop/kernel/kernel32/kernel' 
rm -f *.out *.img *.sym 

[[email protected] kernel32]$ make all 
make -C boot all 
make[1]: Entering directory '/home/cad/Desktop/kernel/kernel32/boot' 
m4 ../m4/global.m4 m4/boot.m4 m4/asm.m4 ../m4/asm.m4 main.S | \ 
as -o main.o --32 -g 
m4 ../m4/global.m4 m4/boot.m4 m4/asm.m4 ../m4/asm.m4 boot.S | \ 
as -o boot.o --32 -g 
m4 ../m4/global.m4 m4/boot.m4 m4/asm.m4 ../m4/asm.m4 floppy_errs.S | \ 
as -o floppy_errs.o --32 -g 
m4 ../m4/global.m4 m4/boot.m4 m4/asm.m4 ../m4/asm.m4 install_ints.S | \ 
as -o install_ints.o --32 -g 
m4 ../m4/global.m4 m4/boot.m4 m4/asm.m4 ../m4/asm.m4 drivers/i8259A.S | \ 
as -o drivers/i8259A.o --32 -g 
m4 ../m4/global.m4 m4/boot.m4 m4/asm.m4 ../m4/asm.m4 drivers/i8042.S | \ 
as -o drivers/i8042.o --32 -g 
m4 ../m4/global.m4 m4/boot.m4 m4/asm.m4 ../m4/asm.m4 drivers/vga.S | \ 
as -o drivers/vga.o --32 -g 
m4 ../m4/global.m4 m4/boot.m4 boot.ld > boot.ld.m4 
ld -T boot.ld.m4 main.o boot.o floppy_errs.o install_ints.o drivers/i8259A.o drvers/i8042.o drivers/vga.o -melf_i386 
make[1]: Leaving directory '/home/cad/Desktop/kernel/kernel32/boot' 
objcopy --only-keep-debug boot.out boot.sym 
objcopy --strip-debug --strip-unneeded boot.out 
objcopy -O binary boot.out boot.img 

[[email protected] kernel32]$ make all 
objcopy --only-keep-debug boot.out boot.sym # HERE 

[[email protected] kernel32]$ make all 
make: Nothing to be done for 'all'. 

は(私は# HEREで該当する行をマークし、私も読みやすくするために空白行を挿入する。。)

事これは一見無作為に起こるということです。実際、私が与えた2つの例は、連続して起こった。私はmake cleanmake all、およびmake all時々間の長い時間を一緒にしっかりをコマンドを実行するのに対し、冗長ビルドステップを発生させたことに気づいた
はそれを引き起こしたことはありません
。私はちょうど10倍のようにしました。次のように

メイクファイルは次のとおりです。

# Parameters passed to GNU make. 
# `dbg=y|n': decides whether debugging mode is on or not. 
# `sep_boot=y|n': decides whether bootloader and kernel should be seperate 
# images or not. 
# TODO: add functionality for these parameters 

SHELL = /bin/bash 

%.sym: %.out 
     objcopy --only-keep-debug $< [email protected] 

%.img: %.out 
     objcopy --strip-debug --strip-unneeded $< 
     objcopy -O binary $< [email protected] 

%.out: 
     make -C $* all 

# TODO: merge run and debug targets and decide to debug or not using the dbg 
# parameter. 

boot_debug: boot.sym boot.img 
     qemu-system-i386 -fda boot.img -s -S & 
     gdb -x dbg.gdb 

all: boot.sym boot.img #kernel.img kernel.sym 

boot.sym boot.img: boot.out 

kernel.sym kernel.img: kernel.out 


clean: 
     make -C boot clean 
     make -C kernel clean 
     rm -f *.out *.img *.sym 


.PHONY: boot_debug all clean 

自分で再現したい場合は、gitのクローンがhereをダウンロードすることができます。

ここで何が問題なのですか?そして、追加のビルドステップとコマンド間の時間との相関はどこにありますか(またはそれはちょうど誤観察ですか?) GNU makeはタイムスタンプに依存してファイルの最新バージョンを判断します...多分それは何とか関連していますか?

答えて

2

さて、このルールのレシピの最初のライン:

%.img: %.out 
     objcopy --strip-debug --strip-unneeded $< 
     objcopy -O binary $< [email protected] 

は、そのタイムスタンプを更新し、その前提(boot.out)を、修正されています。それがいつ起こったのか、あなたが持っているファイルシステムの種類(例えば秒未満のタイムスタンプをサポートしているかどうかなど)によっては、このルールが完了した後に、boot.outのタイムスタンプが以前に作成されたタイムスタンプboot.symとなりますので、makeを再実行すると、boot.symを再構築することになります。

このルールは前提条件を変更しないように書き直す必要があります。多分:objcopyをは標準入力から読み込み、標準出力/に書き込みするかどう

%.img: %.out 
     objcopy --strip-debug --strip-unneeded $< $<.tmp 
     objcopy -O binary $<.tmp [email protected] 
     rm -f $<.tmp 

私はわからないんだけど、もしそうなら、あなたは代わりにパイプラインを使用することができます。

関連する問題