How to get current relative directory of your Makefile?


As taken from here;

ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

Shows up as;

$ cd /home/user/

$ make -f test/Makefile 

$ cd test; make Makefile 

Hope this helps


I have a several Makefiles in app specific directories like this:


Each Makefile includes a .inc file in this path one level up:


Inside I'm setting the destination of where I want the binaries to be placed when built. I want all binaries to be in their respective app_type path:


I tried using $(CURDIR), like this:

OUTPUT_PATH = /project1/bin/$(CURDIR)

but instead I got the binaries buried in the entire path name like this: (notice the redundancy)


What can I do to get the "current directory" of execution so that I can know just the app_typeX in order to put the binaries in their respective types folder?

I like the chosen answer, but I think it would be more helpful to actually show it working than explain it.


#!/bin/bash -eu

# Create a testing dir
mkdir -p $proj_dir

# Create the Makefile in $proj_dir
# (Because of this, $proj_dir is what $(path) should evaluate to.)
cat > $proj_dir/Makefile <<'EOF'
path := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
cwd  := $(shell pwd)

    @echo "         path: $(path)"
    @echo "          cwd: $(cwd)"
    @echo ""

# See/debug each command
set -x

# Test using the Makefile in the current directory
cd $proj_dir

# Test passing a Makefile
cd $temp_dir
make -f $proj_dir/Makefile

# Cleanup
rm -rf $temp_dir


+ cd /tmp/makefile_path_test/dir1/dir2/dir3
+ make
         path: /private/tmp/makefile_path_test/dir1/dir2/dir3
          cwd: /tmp/makefile_path_test/dir1/dir2/dir3

+ cd /tmp/makefile_path_test
+ make -f /tmp/makefile_path_test/dir1/dir2/dir3/Makefile
MAKEFILE_LIST:  /tmp/makefile_path_test/dir1/dir2/dir3/Makefile
         path: /tmp/makefile_path_test/dir1/dir2/dir3
          cwd: /tmp/makefile_path_test

+ rm -rf /tmp/makefile_path_test

NOTE: The function $(patsubst %/,%,[path/goes/here/]) is used to strip the trailing slash.

Here is one-liner to get absolute path to your Makefile file using shell syntax:

SHELL := /bin/bash
CWD := $(shell cd -P -- '$(shell dirname -- "$0")' && pwd -P)

And here is version without shell based on @0xff answer:

CWD=$(abspath $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))

Test it by printing it, like:

        @echo $(CWD)

THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

Putting together the examples given here, this gives the full path to the makefile:

# Get the location of this makefile.
ROOT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))