user2274696
user2274696

Reputation: 81

make, write a rule for single file

I need a file to have a dedicated rule for use special flags. Now I use

$(OBJDIR)/%.$(OE): special_file.c
    $(ECHO) "Compiling file $< => $@" 
    $(CC)  $(CFLAGS) $(CFLAGS_SPECIAL) $(DEFINES) $(INCLUDE) $< -o $@

$(OBJDIR)/%.$(OE): %.c $(OBJDIR)
    $(ECHO) "Compiling file $< => $@" 
    $(CC)  $(CFLAGS) $(DEFINES) $(INCLUDE) $< -o $@

But isn't working for special_file.c. It seems the path is not known, but when I comment my special rule and let make all files, file is compiling fine.

How to divert make to a rule just for one file?

Thanks very much in advance,

Upvotes: 0

Views: 123

Answers (2)

MadScientist
MadScientist

Reputation: 100836

If you want to do it this way, you'll have to write it as a static rule:

$(OBJDIR)/special_file.$(OE): special_file.c
        $(ECHO) "Compiling file $< => $@" 
        $(CC)  $(CFLAGS) $(CFLAGS_SPECIAL) $(DEFINES) $(INCLUDE) $< -o $@

However, much simpler and more flexible is to use recursive variable naming. Do something like this:

special_file_FLAGS = $(CFLAGS_SPECIAL)

$(OBJDIR)/%.$(OE): %.c
        $(ECHO) "Compiling file $< => $@" 
        $(CC)  $(CFLAGS) $($*_FLAGS) $(DEFINES) $(INCLUDE) $< -o $@

The automatic variable $* expands to the stem (the part that matches %). Now when you build anything other than special_file.c, say other_file.c, make will expand $(other_file_FLAGS) which is empty. When you build special_file.c, make will expand $(special_file_FLAGS).

BTW, you should (almost) never list a directory as a prerequisite of a target. Search for other answers to find out why not and the right way to ensure the target directory is created.

ETA:

Target-specific variables are definitely a cool feature. I tend to not use them, though. Why? Because I prefer to separate my data from my rules.

If you use target-specific variables, you are mixing together the rule syntax (the target) with the data syntax (the variable assignment). Using the recursive variable name method, I keep the rule syntax and the data assignment separate. What if I decide I need to change my pattern rule so that the target name changes? With target-specific variables I have to go through all my files and change the target names. With recursive variable naming, I just change the pattern rule and it Just Works.

In my build environments I typically have makefiles containing only data (variable assignments), plus an include of a common makefile that declares all my rules. Avoiding the need to leak target formatting syntax all over my general data-driven makefiles, escaping from my uber-magical common rule definitions, keeps me from doing much with target-specific variables.

Upvotes: 1

Shaac
Shaac

Reputation: 195

You should use Target-specific Variable Values:

$(OBJDIR)/special_file.$(OE): CFLAGS += --specific_flags
$(OBJDIR)/special_file.$(OE): special_file.c

$(OBJDIR)/%.$(OE): %.c $(OBJDIR)
    $(ECHO) "Compiling file $< => $@" 
    $(CC)  $(CFLAGS) $(DEFINES) $(INCLUDE) $< -o $@

Upvotes: 4

Related Questions