Search code examples
makefilegnu

GNU Makefile Multiple rules in multiple targets


I am doing a nasm project, and I need to execute the ej and use as a parameter the ex.asm . I tried searching through GNU how can I pick one by one the parameter. My solution has been writing ex1_ and ex2_, but I want to put those inside the $(ex) dependency, so I don't have to replicate multiple times the same code. Is there any way?

Thank you in advance

The code:

ej = ej1_gen ej2_gen
ex = ex1     ex2

# -----------------------------------------------
all: $(ej) $(ex)
exs: ex1_ ex2_ 
# -----------------------------------------------

$(ex): exs
    nasm -g -o $@.o -f elf32 $@.asm
    $(CC) $(FLAGS) -m32 -o $@ $@.o alfalib.o

ex1_:
    ./ej1_gen ex1.asm
ex2_:
    ./ej2_gen ex2.asm

Solution

  • As I read the question, you have programs or scripts ej1_gen and ej2_jen in the project, serving to generate the wanted assembly sources. They each take the name of the output file as a command-line argument. Parts of this answer would need to be adjusted if that's a misinterpretation.


    Rules to describe how to build the assembly files should designate the resulting assembly file(s) as the target. Also, supposing that the code-generator programs are part of the project, they should be designated as prerequisites, since changing those could cause them to produce different outputs. Any configuration files or similar that they read to inform their results should also be named as prerequisites (not shown). That leads to rules something like this:

    ex1.asm: ej1_gen
        ./ej1_gen $@
    
    ex2.asm: ej2_gen
        ./ej2_gen $@
    

    It sounds like you may be asking for a way to express that via just one rule covering both, but I would not do so in this case. I don't think you get any clearer than the above, even if there are more than two assembly files to generate. It might be different if the same code generator program were being used, with different options, to generate all the assembly files, or perhaps if the generator name could be derived more directly from the target name.

    With those rules in place, you can write a generic suffix rule or pattern rule to assemble the resulting files. Since you tag [gnu], I'll assume that a pattern rule is acceptable:

    %.o: %.asm
        nasm -g -o $@ -f elf32 $<
    

    And you can take a similar approach to expressing a link rule:

    %: %.o alfalib.o
        $(CC) $(FLAGS) -m32 -o $@ $^
    

    With that, you should be able to get rid of the ej variable and the exs target, too, leaving

    all: $(ex)
    

    as the only other rule (and it should still appear first in the file, as it does now).