antoine_co
antoine_co

Reputation: 20

GNU Makefile : How to use pattern-rule adding a compilation flag to a match-anything pattern-rule by using pattern-specific variable value?

I have created several test files test_*.c, each testing a single function of a c library I built.

I first wrote a Makefile for compiling each c file to produce its corresponding binary:

TEST_SRCS       =   ${wildcard *.c}

TEST_EXECS      =   ${TEST_SRCS:.c=}

PROJECT_PATH    =   ../my_project

CFLAGS          =   -Wall -Wextra -Werror

%::         %.c ${PROJECT_PATH}/libmyproject.a
            gcc ${CFLAGS} $< -L${PROJECT_PATH} -lmyproject -o $@

all:        ${TEST_EXECS}

clean:
            rm -f ${TEST_EXECS}

re:         clean all

.PHONY:     all clean re

This works as expected, so when i type make test_<name_of_my_function> and if the 'test_<name_of_my_function>.c' file exists, it compiles it to create the 'test_<name_of_my_function>' binary.

But now i want to add a rule that creates the binary in debug mode by adding the gcc flag -g to the command if i run the command make debug_test_<name_of_my_function>.

I tried adding the pattern-specific rule debug_% and use a pattern-specific value for appending -g to CFLAGS:

TEST_SRCS       =   ${wildcard *.c}

TEST_EXECS      =   ${TEST_SRCS:.c=}

PROJECT_PATH    =   ../my_project

CFLAGS          =   -Wall -Wextra -Werror

%::         %.c ${PROJECT_PATH}/libmyproject.a
            gcc ${CFLAGS} $< -L${PROJECT_PATH} -lmyproject -o $@

all:        ${TEST_EXECS}

debug_%:    CFLAGS += -g
debug_%:    %

clean:
            rm -f ${TEST_EXECS}

re:         clean all

.PHONY:     all clean re

But when i run for example debug_test_function1, i get the following ouptut :

make: *** No rule to make target 'debug_test_function1'.  Stop.

Note that whatever prerequisite rule i use for the target debug_%, it isn't executed (even if the prerequisite is not a pattern rule).

Note also that if i replace in the makefile

debug_%:    CFLAGS += -g
debug_%:    %

by

debug%:     %.c ${PROJECT_PATH}/libft.a
            gcc ${CFLAGS} -g $< -L${PROJECT_PATH} -lmyproject -o $@

it works. But i'd lose the benefit of using a pattern-specific variable here.

Any clue oh how to use pattern-specific variable values to do it?

Thank you for your help !

Upvotes: 0

Views: 228

Answers (1)

MadScientist
MadScientist

Reputation: 100836

This:

debug_%:    %

does not define a pattern rule. It deletes a pattern rule. See the GNU make manual. So, you've not defined any rules here that know how to build debug_test_function1 (because there's no file debug_test_function1.c to build it from and the only rule you have available is the match-anything rule).

You have to provide the recipe here, you cannot omit it. But obviously you can still add a pattern-specific variable; why not?:

debug_%:    CFLAGS += -g
debug_%:    %.c ${PROJECT_PATH}/libft.a
        gcc ${CFLAGS} $< -L${PROJECT_PATH} -lmyproject -o $@

I'm not really sure what "benefit of pattern-specific variables" you are referring to since you don't seem to build an other prerequisites that need to inherit the pattern-specific variable. But the above should work.

Upvotes: 2

Related Questions