9

What is the simplest code to get the top-level directory part of a makefile variable? Example:

BUILD_DIR = dir/subdir/.../sub-a-dub-dir
distclean:
        rm -rf <some code which evaluates to "dir" from $(BUILD_DIR)>

PS: I don't mean $(dir $(dir $(BUILD_DIR))), but something which gets the first directory part of any variable value.

6
  • dirname /tmp/foo/bar will give /tmp or dirname foo/bar/baz will give foo
    – Abhishek A
    Nov 9, 2011 at 15:42
  • 1
    @greenmang0: Flagged your answer. First, it's plain wrong (did you even execute those commands?), and second it's for a makefile, not Bash.
    – l0b0
    Nov 9, 2011 at 16:18
  • @l0b0 It's a comment, and "it's wrong" isn't a good reason to flag anything, just leave a comment saying what the problem is Nov 9, 2011 at 16:23
  • @MichaelMrozek: I flagged it "not constructive / off topic", both of which applies to it.
    – l0b0
    Nov 9, 2011 at 19:51
  • I don't understand your question: what do you mean by “the top-level directory part”? Do you mean the part before the first /? Do you guarantee that the argument is a relative path? Are you assuming GNU make? Nov 9, 2011 at 23:05

2 Answers 2

6

Do you mean the first component of the directory? If so, turn the path into a list of components, then extract the first component. I assume you're using GNU make, and you're not doing something insane like expect file names with whitespace to go through unscathed. Don't try this with an absolute path.

override BUILD_DIR = dir/subdir/.../sub-a-dub-dir
distclean:
        rm -rf $(firstword $(subst /, ,$(BUILD_DIR)))

I make BUILD_DIR override whatever the user might have passed on the command line, to avoid someone accidentally passing it and having something unintended deleted.

2
  • BUILD_DIR was supposed to be an internal variable, but you're right, there's still the possibility that someone sets it to something dangerous. So accepting this answer, with the caveat that the solution should not be used :)
    – l0b0
    Feb 17, 2012 at 8:39
  • 1
    @l0b0 Since we're assuming GNU make: override BUILD_DIR = … Feb 17, 2012 at 8:43
0

If you're positive that BUILD_DIR will never start with a '/':

rootdir=$( echo $BUILD_DIR | cut -d/ -f1 )

Otherwise, you might need to account for paths that start with '/':

if [[ $BUILD_DIR =~ "^/" ]]; then
        rootdir=$( echo $BUILD_DIR | cut -d/ -f1,2 )
else
        rootdir=$( echo $BUILD_DIR | cut -d/ -f1 )
fi

echo $rootdir

Or maybe it's best to ignore any path that starts with '/'.

2
  • 1
    This is for a makefile, not Bash. This is a trivial problem in Bash, but I'm interested in a simple makefile solution.
    – l0b0
    Nov 9, 2011 at 16:14
  • One thing you can do in a Makefile is run commands. So you create a shell script, in your path, called rootdir, and in your makefile, run "rm -rf $(rootdir $BUILD_DIR)", or something like that. Or you'll have to do something like pre-define the build root, so that you can rm -rf it later. I would definitely doublecheck the response that the rootdir script can pass back, so you don't end up with a syntax error giving your script rm -rf /. Nov 9, 2011 at 16:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .