4

現在、まったく同じであるが別のフラグをコンパイラに渡す実行可能ファイルをビルドするために、プロジェクト Makefile を変更しています。

変更前の Makefile は次のようになっていました。

    TARGETS = elilo.efi

    all : check_gcc $(SUBDIRS) $(TARGETS)

    elilo.efi : elilo.so

    elilo.so : $(FILES)
    elilo.o : elilo.c $(ARCH)/sysdeps.h
    ...
    $(SUBDIRS): dummy
        $(MAKE) -C $@
    ...
    include Make.rules

どこ:

  • $(SUBDIRS)プロジェクトのすべてのサブディレクトリを保存します
  • $(FILES)、elilo.soをリンクするために作成する必要があるすべての.oファイルを保存します
  • そしてcheck_gcc、コンパイラのバージョンをチェックし、必要に応じて終了します

さらに、Make.rules には、ファイルをコンパイルおよびリンクするための一般的な規則が含まれています。

%.efi: %.so 
    $(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \
           -j .rela -j .reloc --target=$(FORMAT) $*.so $@

%.so: %.o 
    $(LD) $(LDFLAGS) $^ -o $@ $(LOADLIBES)

%.o: %.c         # Rule number 1
    $(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
# a rule for .S
%.o: %.S 
    $(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c $< -o $@

私の試み:

これまでのところ、新しいターゲットを持ち、すべてのルールで両方をコンパイルできるようにするために、次のことを試しました

TARGETS = elilo.efi usb

all : $(TARGETS)

elilo.efi : check_gcc $(SUBDIRS) elilo.so
        touch $@.touch

elilo.so : $(FILES)

.PHONY : usb
usb : check_gcc $(SUBDIRS)
    CFLAGS += "-DBoot64" $(MAKE) boot64.efi
    touch $@.touch

boot64.efi : elilo.so
    $(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \
           -j .rela -j .reloc --target=$(FORMAT) $> $@

Make.rules を使用:

%.efi: %.so 
    $(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \
           -j .rela -j .reloc --target=$(FORMAT) $*.so $@

%.so: %.o
    $(LD) $(LDFLAGS) $^ -o $@ $(LOADLIBES)

%.o: %.c usb.touch elilo.touch     # Rule number 1
    $(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
...

しかし、ルール番号 1に加えた変更のようには見えません$(SUBDIRS)。おそらく、そのルールは非常に一般的であり、プロジェクト ディレクトリとそのサブディレクトリ内のすべてのオブジェクト ファイルに影響するためです...

基本的に、私がやりたいことは、elilo.efi と同じように boot64.efi をビルドすることですが、フラグ -DBoot64 をコンパイラに渡して、一部の .c ファイルがその動作を変更するようにします。それを行う方法に関するヒントはありますか?

4

2 に答える 2

1

ようやく解決にたどり着いたと思います。Make.rules の「プロトタイプ」ルールを変更する代わりに。bootx64.efi をビルドするための新しい別のパスをビルドしたので、elilo.efi がビルドされるのと同じ方法でビルドされます。

コードは次のとおりです。

all : check_gcc $(TARGETS)

######################## NORMAL ELILO ################################

elilo : $(SUBDIRS)
    $(MAKE) elilo.efi
    rm -f $(FILES)

elilo.efi : elilo.so

elilo.so : elilo.o $(FILES)

elilo.o : elilo.c $(ARCH)/sysdeps.h

############################ USB ELILO ###############################
# SUBDIRS must be build using a for, as if not done so, make 
# would take the rule as executed and SUBDIRS wouldn't be compiled 
# with the new flag

usb :
    for dir in $(SUBDIRS); do \
      $(MAKE) -C $$dir CFLAGS="$(CFLAGS) -DBOOTX64"; \
    done
    $(MAKE) bootx64.efi CFLAGS="$(CFLAGS) -DBOOTX64"

bootx64.efi : bootx64.so

bootx64.so : bootx64.o $(FILES)

# bootx64.o is build the same way elilo.o is build (code from the 
# prototype rules has been copied)

bootx64.o : elilo.c $(ARCH)/sysdeps.h
    $(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c $< -o $@

#######################################################################

最後に、$(FILES) 変数が変更され、elilo.o と bootx64.o が .so ファイルを区別するため、そこから elilo.o が取り出されました。現在、この .o ファイルは、対応する各ルールでハードコードされています。

于 2013-08-09T10:43:18.750 に答える
1

次のように elilo.so を RM する必要があると思います:

usb : check_gcc $(SUBDIRS)
    rm elilo.so
    CFLAGS += "-DBoot64" $(MAKE) boot64.efi
    touch $@.touch

elilo.so が「Boot64」なしで既にビルドされている場合、再ビルドされないためです。

于 2013-07-25T13:22:11.303 に答える