简体   繁体   中英

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

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?

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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM