Search code examples
makefilecompilationgnu-makeexecutablerules

How to add suffix to a string in a Makefile rule when having multiple targets?


My goal is to have a single Makefile that compiles multiple executables all in the same directory. OBJ contains all the .o files except the mains.o which I plan to add only when compiling the specific executable. The logic is this: calling "make all" will try to build main1 first using OBJ and main1.o, but I don't know how to specify main1.o! I thought of using automatic variable $@ to get the target and append to it the .o extension but it does not work.

EXE_ALL = main1 main2 main3
all: $(EXE_ALL)

$(EXE_ALL): $(OBJ) $($@:=.o) # <--- here I don't know how to add the current mains.o?

I know that a multiple target should expand to.

main1: $(OBJ) main1.o
main2: $(OBJ) main2.o
main3: $(OBJ) main3.o

For now it just builds everything but doesn't build the mains.o files, it will build the executables directly (they all work, but I want also the mains.o) like this: main1.cpp OBJ -> main1.

Any help is appreciated. Thanks.


Solution

  • In order to resolve $@ in a prerequisite list you need to turn on secondary expansion, like so:

    $ cat Makefile
    EXE_ALL = main1 main2 main3
    OBJ = whatever.o
    
    .PHONY: all
    all: $(EXE_ALL)
    
    .SECONDEXPANSION:
    $(EXE_ALL): $(OBJ) [email protected]
            @echo Making $@ from $^
    
    %.o:
            @echo Making $@
    

    Output:

    $ make
    Making whatever.o
    Making main1.o
    Making main1 from whatever.o main1.o
    Making main2.o
    Making main2 from whatever.o main2.o
    Making main3.o
    Making main3 from whatever.o main3.o