Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question
    
dirname /tmp/foo/bar will give /tmp or dirname foo/bar/baz will give foo –  greenmang0 Nov 9 '11 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 '11 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 –  Michael Mrozek Nov 9 '11 at 16:23
    
@MichaelMrozek: I flagged it "not constructive / off topic", both of which applies to it. –  l0b0 Nov 9 '11 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? –  Gilles Nov 9 '11 at 23:05

2 Answers 2

up vote 1 down vote accepted

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.

share|improve this answer
    
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 '12 at 8:39
1  
@l0b0 Since we're assuming GNU make: override BUILD_DIR = … –  Gilles Feb 17 '12 at 8:43

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 '/'.

share|improve this answer
    
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 '11 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 /. –  Tim Kennedy Nov 9 '11 at 16:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.