How to check if a directory doesn't exist in make and create it

25,205

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.

Share:
25,205
corazza
Author by

corazza

flowing.systems

Updated on July 23, 2020

Comments

  • corazza
    corazza almost 4 years

    In my project's directory, I have some subdirs: code/, export/, docs/ and object/. What make 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 the object/ 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
    Idelic over 11 years
    It is often preferable to use an order-only prerequisite for this (that is, use code/%.cc | object), so that object does not affect $^.
  • Beta
    Beta over 11 years
    @Idelic: neat trick, I didn't know that $^ didn't include order-only preqs. Thanks!
  • iheanyi
    iheanyi almost 10 years
    So, I couldn't for example have a target called "debug" and a folder called "debug". . .
  • Alexandro de Oliveira
    Alexandro de Oliveira over 6 years
    Good 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
    MarcH over 5 years
    Works but less optimal: forks a shell process every time as opposed to just when required.
  • mookid
    mookid about 3 years
    this 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.