【问题标题】:Get makefile to build two targets from the same file but with different flags获取 makefile 以从同一个文件构建两个目标,但具有不同的标志
【发布时间】:2013-07-25 09:23:36
【问题描述】:

我目前正在更改项目 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 文件会改变其行为。关于如何做到这一点的任何提示?

【问题讨论】:

    标签: makefile dependencies gnu-make


    【解决方案1】:

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

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

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

    【讨论】:

    • 到目前为止我所做的更改,它甚至没有到达那里,它在执行 $(SUBDIRS) 时卡住了(我认为这与我添加到 Rule 的依赖项有关第 1 号)
    【解决方案2】:

    我想我终于找到了解决方案。而不是修改 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 文件被硬编码在 每个对应的规则。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-15
      相关资源
      最近更新 更多