Pedriyoo
Pedriyoo

Reputation: 1259

Get makefile to build two targets from the same file but with different flags

I'm currently changing a project Makefile in order to build an executable that is exactly the same but passing a different flag to the compiler.

Before changing it, the Makefile was like this:

    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

Where:

Additionally, Make.rules contains general rules to compile and link files:

%.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 $@

MY TRY:

So far, I've tried the following in order to have a new target and be able to compile them both with all rule

TARGETS = elilo.efi usb

all : $(TARGETS)

elilo.efi : check_gcc $(SUBDIRS) elilo.so
        touch [email protected]

elilo.so : $(FILES)

.PHONY : usb
usb : check_gcc $(SUBDIRS)
    CFLAGS += "-DBoot64" $(MAKE) boot64.efi
    touch [email protected]

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

With 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 $@
...

But it doesn't look like the change I've made to the Rule Number 1 as it now stops when making $(SUBDIRS), probably because that rule is so general that it affects every object file in the project directory and its sub-directories...

Basically, what I want to do is build boot64.efi just like elilo.efi but passing the flag -DBoot64 to the compiler so some .c files change its behaviour. Any tips on how to do that?

Upvotes: 4

Views: 2197

Answers (2)

Pedriyoo
Pedriyoo

Reputation: 1259

I think I've finally arrived to the solution. Instead of modifying the "prototype" rules in Make.rules. I have build a new different path to build bootx64.efi, so it gets build the same way that elilo.efi gets build.

Here comes the code:

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 $@

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

Finally, $(FILES) variable has been modified, taken out elilo.o from it, as elilo.o, and bootx64.o are what distinguish .so files. Now this .o files are hardcoded in each corresponding rule.

Upvotes: 1

Mali
Mali

Reputation: 2700

I Think you shoud rm elilo.so like this :

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

because if elilo.so is already build without "Boot64" it won't be rebuild

Upvotes: 1

Related Questions