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), 存储所有必须创建的 .o 文件以链接 elilo.so
  • 只需检查编译器版本并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所做的更改,因为它现在在 make 时停止$(SUBDIRS),可能是因为该规则太笼统以至于它影响项目目录及其子目录中的每个目标文件......

基本上,我想做的是像 elilo.efi 一样构建 boot64.efi,但将标志 -DBoot64 传递给编译器,因此一些 .c 文件会改变其行为。关于如何做到这一点的任何提示?

4

2 回答 2

1

我认为你应该 rm elilo.so 像这样:

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

因为如果 elilo.so 已经在没有“Boot64”的情况下构建,它将不会被重建

于 2013-07-25T13:22:11.303 回答
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,因为elilo.o和bootx64.o是区分.so文件的地方。现在这个 .o 文件被硬编码在每个相应的规则中。

于 2013-08-09T10:43:18.750 回答