Reputation: 81
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
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
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