97

私が取り組んでいるプログラム (実際にはカーネル) を構築するために使用する次の makefile があります。それはゼロからであり、私はプロセスについて学んでいるので、完璧ではありませんが、この時点でメイクファイルを書いた経験のレベルには十分強力だと思います.

AS  =   nasm
CC  =   gcc
LD  =   ld

TARGET      =   core
BUILD       =   build
SOURCES     =   source
INCLUDE     =   include
ASM         =   assembly

VPATH = $(SOURCES)

CFLAGS  =   -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions \
            -nostdinc -fno-builtin -I $(INCLUDE)
ASFLAGS =   -f elf

#CFILES     =   core.c consoleio.c system.c
CFILES      =   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
SFILES      =   assembly/start.asm

SOBJS   =   $(SFILES:.asm=.o)
COBJS   =   $(CFILES:.c=.o)
OBJS    =   $(SOBJS) $(COBJS)

build : $(TARGET).img

$(TARGET).img : $(TARGET).elf
    c:/python26/python.exe concat.py stage1 stage2 pad.bin core.elf floppy.img

$(TARGET).elf : $(OBJS)
    $(LD) -T link.ld -o $@ $^

$(SOBJS) : $(SFILES)
    $(AS) $(ASFLAGS) $< -o $@

%.o: %.c
    @echo Compiling $<...
    $(CC) $(CFLAGS) -c -o $@ $<

#Clean Script - Should clear out all .o files everywhere and all that.
clean:
    -del *.img
    -del *.o
    -del assembly\*.o
    -del core.elf

この makefile に関する私の主な問題は、1 つまたは複数の C ファイルに含まれるヘッダー ファイルを変更すると、C ファイルが再構築されないことです。すべてのヘッダー ファイルをすべての C ファイルの依存関係にすることで、これを非常に簡単に修正できますが、ヘッダー ファイルを変更または追加するたびに、プロジェクトの完全な再構築が事実上発生します。これはあまり適切ではありません。

私が望むのは、変更したヘッダー ファイルを含むC ファイルのみをリビルドし、プロジェクト全体を再度リンクすることです。すべてのヘッダー ファイルをターゲットの依存関係にすることでリンクを実行できますが、含まれているヘッダー ファイルが新しい場合に C ファイルを無効にする方法がわかりません。

GCCにはこれを可能にするコマンドがいくつかあると聞いたことがあります(そのため、makefileはどのファイルを再構築する必要があるかをどうにかして把握できます)が、実際の実装例を見ることができません。メイクファイルでこの動作を有効にするソリューションを誰かが投稿できますか?

編集:明確にする必要があります。個々のターゲットを配置し、各 target.o にヘッダーファイルを必要とするという概念に精通しています。そのため、どこかにヘッダー ファイルをインクルードするたびにメイクファイルを編集する必要があり、これは少し面倒です。ヘッダー ファイルの依存関係を独自に導出できるソリューションを探しています。これは、他のプロジェクトで見たことがあると確信しています。

4

9 に答える 9

33

このサイトの他の場所で既に指摘されているように、次のページを参照してください: Auto-Dependency Generation

つまり、gcc は自動的に .d 依存関係ファイルを作成できます。これは、コンパイルした .c ファイルの依存関係を含む小さな makefile フラグメントです。.c ファイルを変更してコンパイルするたびに、.d ファイルが更新されます。

-M フラグを gcc に追加するだけでなく、makefile に .d ファイルを含める必要があります (Chris が上で書いたように)。このページには、sed を使用して解決できるさらに複雑な問題がいくつかありますが、存在しないヘッダー ファイルを作成できないという make のエラーが発生した場合は、それらを無視して「make clean」を実行して .d ファイルを消去することができます。 .

于 2009-03-09T13:47:57.710 に答える
21

他の人が述べているように、「makedepend」コマンドを追加できますが、gccで依存関係を作成して同時にコンパイルしないのはなぜですか:

DEPS := $(COBJS:.o=.d)

-include $(DEPS)

%.o: %.c
    $(CC) -c $(CFLAGS) -MM -MF $(patsubst %.o,%.d,$@) -o $@ $<

「-MF」パラメーターは、依存関係を保管するファイルを指定します。

「-include」の先頭のダッシュは、.d ファイルが存在しない場合 (最初のコンパイル時など) に続行するように Make に指示します。

-o オプションに関して gcc にバグがあるようです。オブジェクト ファイル名を say に設定するとobj/_file__c.o、生成されたファイルにはではなく_file_.dが含まれます。_file_.oobj/_file_c.o

于 2010-03-23T16:20:28.033 に答える
17

これはChrisDoddの答えと同等ですが、異なる命名規則を使用します(そして、偶然にもsed魔法は必要ありません。後の複製からコピーされます。


GNUコンパイラを使用している場合、コンパイラは依存関係のリストをアセンブルできます。Makefileフラグメント:

depend: .depend

.depend: $(SOURCES)
        rm -f ./.depend
        $(CC) $(CFLAGS) -MM $^>>./.depend;

include .depend

ツールもありますがmakedepend、あまり好きではありませんでしたgcc -MM

于 2010-03-07T00:42:18.583 に答える
8

C ファイルごとに個別のターゲットを作成し、ヘッダー ファイルを依存関係としてリストする必要があります。ジェネリック ターゲットを引き続き使用して、.h後で次のように依存関係を配置することができます。

%.o: %.c
        @echo Compiling $<...
        $(CC) $(CFLAGS) -c -o $@ $<

foo.c: bar.h
# And so on...
于 2008-11-18T00:59:40.060 に答える
4

基本的には、ヘッダー ファイルが変更されたときにオブジェクト ファイルを再構築するためのメイクファイル ルールを動的に作成する必要があります。gcc と gnumake を使用している場合、これはかなり簡単です。次のようなものを入れてください:

$(OBJDIR)/%.d: %.c
        $(CC) -MM -MG $(CPPFLAGS) $< | sed -e 's,^\([^:]*\)\.o[ ]*:,$(@D)/\1.o $(@D)/\1.d:,' >$@

ifneq ($(MAKECMDGOALS),clean)
include $(SRCS:%.c=$(OBJDIR)/%.d)
endif

あなたのメイクファイルで。

于 2008-11-18T01:08:36.343 に答える
3

より簡単な解決策: Makefile を使用して、.c から .o へのコンパイル ルールがヘッダー ファイルに依存するようにし、プロジェクトに依存関係として関連するものは何でもかまいません。

たとえば、どこかの Makefile で:

DEPENDENCIES=mydefs.h yourdefs.h Makefile GameOfThrones.S07E01.mkv

::: (your other Makefile statements like rules 
:::  for constructing executables or libraries)

# Compile any .c to the corresponding .o file:
%.o: %.c $(DEPENDENCIES)
        $(CC) $(CFLAGS) -c -o $@ $<
于 2016-09-02T15:59:40.710 に答える
3

@mipadi が言ったことに加えて、「-M」オプションを使用して依存関係の記録を生成することもできます。それらを別のファイル (おそらく「depend.mk」) に生成してから、makefile に含めることもできます。make dependまたは、makefile を正しい依存関係 (Google 用語: 「この行を削除しないでください」と依存) で編集 する ' ' ルールを見つけることができます。

于 2008-11-18T01:06:17.240 に答える
-1

コマンドmkdepはあなたが望むものだと思います。実際に.cファイルの#include行をスキャンし、それらの依存関係ツリーを作成します。Automake/Autoconfプロジェクトはデフォルトでこれを使用していると思います。

于 2010-03-07T00:45:15.427 に答える