Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a makefile, is a directory name a phony target or "real" target?

Tags:

According to what I have read about makefiles, a phony target is any target that does not correspond to an actual filename. My intuition says that a directory as a target would be treated the same as a file.

Why is this important? I have a directory as a target in my makefile. when I have it as a prerequisite to my primary executable, that executable always gets made, whether or not everything is up to date. If I take it out as a prerequisite, my makefile is smart enough to know when things need to be built, but I have the problem of not knowing if the directory needs to be created. According to what I have read about make, any phony targets are not good as prerequisites because make does not know if they are up to date, so they will always rebuild the associated target. Here is an excerpt from my makefile.

$(EXEC_WITH_PATH): ${OBJ_DIR} $(DPEND) $(OBJS)     @echo "--------------------------------------------";     @echo "$(THIS_DIR)  $(MACHINE)";     @echo "Linking Shared Library";     @echo "ar -rc $(EXEC_WITH_PATH) INSERT::{OBJS}";     ar -rc $(EXEC_WITH_PATH)  $(OBJS);     @echo "--------------------------------------------";   # Make dirs for object code and links ${OBJ_DIR} :         @if [ ! -d ${OBJ_DIR} ]; then \                 mkdir ${OBJ_DIR};    \         fi; 

So in this case, is ${OBJ_DIR}, a directory name, a phony target or not?

like image 414
Chance Avatar asked Nov 22 '10 17:11

Chance


People also ask

What are phony targets in makefile?

A phony target is one that is not really the name of a file; rather it is just a name for a recipe to be executed when you make an explicit request. There are two reasons to use a phony target: to avoid a conflict with a file of the same name, and to improve performance.

Can makefile target be a directory?

Yes, a Makefile can have a directory as target. Your problem could be that the cd doesn't do what you want: it does cd and the git clone is carried out in the original directory (the one you cd ed from, not the one you cd ed to). This is because for every command in the Makefile an extra shell is created.

What does $@ mean in makefile?

The variable $@ represents the name of the target and $< represents the first prerequisite required to create the output file.

What is a makefile and how does it work?

Makefile sets a set of rules to determine which parts of a program need to be recompile, and issues command to recompile them. Makefile is a way of automating software building procedure and other complex tasks with dependencies. Makefile contains: dependency rules, macros and suffix(or implicit) rules.


2 Answers

Edit: This only applies to GNU make - a fair assumption given the "linux" tag.

Your target is a real target, not a PHONY one. The problem is that the output directory gets updated when you put targets in it so that it is always newer than your target. This means your target will always get built because it is out of date with respect to its dependencies.

What you need is an order-only prerequisite. These prerequisites allow you to specify that it needs to be built if it does not exist, but not to pay attention to the timestamp. That is, a target will not be out of date with respect to order-only prerequisites.

You specify it like this:

$(EXEC_WITH_PATH): $(DPEND) $(OBJS) | ${OBJ_DIR} ... 

Anything after the vertical bar is an order-only prerequisite.

You can now make your OBJ_DIR target simpler:

${OBJ_DIR} :         mkdir -p ${OBJ_DIR} 

Note: I've used the ${OBJ_DIR} syntax instead of $(OBJ_DIR) because that is what you used. Order-only prerequisites do not depend on that syntax.

like image 149
camh Avatar answered Oct 13 '22 21:10

camh


It's a real target.

Phony targets are not detected automatically by the make system - they must be identified by you, using the .PHONY target.

Sensible phony targets include all and clean - these don't correspond to real files, but to actions you want the makefile to do. Here's how to explain this to make:

.PHONY: all clean install test 

Directories are legitimate targets of makefile rules. You should not make these phony.

mydir:      mkdir mydir 

The .PHONY target is of course, phony.

GNU Documentation can be found here.

like image 30
Alex Brown Avatar answered Oct 13 '22 22:10

Alex Brown