Consider the following makefile:
SHELL = /bin/sh
MY_DIR := $(realpath ./)
BASE_DIR := $(realpath ../..)
BASE_SRC_DIR = $(BASE_DIR)/src
BASE_INC_DIR = $(BASE_DIR)/include
HUL_DIR = $(MY_DIR)/hul
JNI_DIR = $(HUL_DIR)/jni
JNI_SRC_DIR = $(JNI_DIR)/src
JNI_INC_DIR = $(JNI_DIR)/include
dirs: $(JNI_SRC_DIR) $(JNI_INC_DIR)
$(JNI_SRC_DIR): $(JNI_DIR)
ln -s $(BASE_SRC_DIR) $@
$(JNI_INC_DIR): $(JNI_DIR)
ln -s $(BASE_INC_DIR) $@
$(JNI_DIR):
mkdir -p $(JNI_DIR)
This makefile creates two symbolic links (JNI_SRC_DIR
and JNI_INC_DIR
) and sets a JNI_DIR
as a dependency for those. All is fine except one thing: calling make dirs
twice creates the links and then links inside those folders. I know this is the standard ln
behaviour when symlinking folders that already exist, I just don't know of any ln
option flag to prevent it without an error (-n
does it but with an error). Anyway, what I'd like to change is make
running the rules for the second time. Apparently it also follows the symlinks, but I just want it to check whether they are there:
Here's a sample output, with three calls:
$ make dirs
mkdir -p /Users/fratelli/Documents/hul/platform/android/hul/jni
ln -s /Users/fratelli/Documents/hul/src /Users/fratelli/Documents/hul/platform/android/hul/jni/src
ln -s /Users/fratelli/Documents/hul/include /Users/fratelli/Documents/hul/platform/android/hul/jni/include
$ make dirs
ln -s /Users/fratelli/Documents/hul/src /Users/fratelli/Documents/hul/platform/android/hul/jni/src
ln -s /Users/fratelli/Documents/hul/include /Users/fratelli/Documents/hul/platform/android/hul/jni/include
$ make dirs
make: Nothing to be done for `dirs'.
I'd like the second time to behave as the third, as the symlinks are already there.
What's happening is that when the symlinks are created by the first make dirs
invocation, the modification time of the directory gets updated. Because you have a dependency on the directory, that means the next time you run make dirs
, make
decides the targets are out of date.
You can change the dependency on $(JNI_DIR)
to be an order-only prerequisite instead, like this:
$(JNI_SRC_DIR): | $(JNI_DIR)
ln -s $(BASE_SRC_DIR) $@
$(JNI_INC_DIR): | $(JNI_DIR)
ln -s $(BASE_INC_DIR) $@
This tells make
to create $(JNI_DIR)
if it doesn't exist, but it won't recreate the links if the directory has been updated.