How to check if a directory doesn't exist in make and create it
Solution 1
Just have a target for it:
object/%.o: code/%.cc object
compile $< somehow...
object:
mkdir $@
You have to be a little more careful if you want to guard against the possibility of a file called "object", but that's the basic idea.
Solution 2
The only correct way to do this is with order-only-prerequisites, see: https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html. Note the | in the snippet.
If you don't use order-only-prerequisites each modification (e.g. coping or creating a file) in that directory will trigger the rule that depends on the directory-creation target again!
object/%.o: code/%.cc | object
compile $< somehow...
object:
mkdir -p $@
Solution 3
Insert a mkdir command in the target.
object/%.o : code/%.cc
@mkdir -p object
compile $< somehow...
The '-p' results in no error if the directory already exists.
Comments
-
corazza almost 4 years
In my project's directory, I have some subdirs:
code/
,export/
,docs/
andobject/
. Whatmake
does is simply compile all the files from the code dir, and put the .o files into the object dir.The problem is, I told git to ignore all .o files, because I don't want them uploaded, so it doesn't track the object dir either. I'm actually OK with that, I don't want the
object/
uploaded to my GitHub account as well, but with the current solution (which is a simple empty text file inside theobject/
dir), the directory does get uploaded and needs to be present before the build (the makefile just assumes it's there).This doesn't really seem like the best solution, so is there a way to check if a directory doesn't exist before the build in a make file, and create it if so? This would allow for the object dir not to be present when the make command is called, and created afterwards.
-
Idelic over 11 yearsIt is often preferable to use an order-only prerequisite for this (that is, use
code/%.cc | object
), so thatobject
does not affect$^
. -
Beta over 11 years@Idelic: neat trick, I didn't know that
$^
didn't include order-only preqs. Thanks! -
iheanyi almost 10 yearsSo, I couldn't for example have a target called "debug" and a folder called "debug". . .
-
Alexandro de Oliveira over 6 yearsGood point! That way it would be created just if it not exist yet, instead of try to create every time the rule is execute (for each object file)
-
MarcH over 5 yearsWorks but less optimal: forks a shell process every time as opposed to just when required.
-
mookid about 3 yearsthis does not work as intended, as the timestamp of the object directory will change when any object if added to it. see the other answer.