wake-up-neo.com

Wie bekomme ich ein aktuelles relatives Verzeichnis Ihres Makefiles?

Ich habe mehrere Makefiles in app-spezifischen Verzeichnissen wie folgt:

/project1/apps/app_typeA/Makefile
/project1/apps/app_typeB/Makefile
/project1/apps/app_typeC/Makefile

Jedes Makefile enthält eine .inc-Datei in diesem Pfad eine Ebene höher:

/project1/apps/app_rules.inc

In app_rules.inc stelle ich das Ziel ein, an dem die Binärdateien beim Erstellen platziert werden sollen. Ich möchte, dass sich alle Binärdateien in ihrem jeweiligen app_type-Pfad befinden:

/project1/bin/app_typeA/

Ich habe es mit $(CURDIR)versucht:

OUTPUT_PATH = /project1/bin/$(CURDIR)

stattdessen habe ich die binaries im gesamten Pfadnamen wie folgt vergraben: (beachte die Redundanz)

/project1/bin/projects/users/bob/project1/apps/app_typeA

Was kann ich tun, um das "aktuelle Verzeichnis" der Ausführung zu erhalten, damit ich nur denapp_typeXkennen kann, um die Binärdateien in den entsprechenden Typenordner zu legen?

154

Die Shell-Funktion.

Sie können Shell function verwenden: current_dir = $(Shell pwd). Oder Shell in Kombination mit notdir , wenn Sie keinen absoluten Pfad benötigen: current_dir = $(notdir $(Shell pwd)).

Aktualisieren.

Die angegebene Lösung funktioniert nur, wenn Sie make im aktuellen Verzeichnis des Makefile ausführen.
Wie @Flimm feststellte:

Beachten Sie, dass dies das aktuelle Arbeitsverzeichnis zurückgibt, nicht das übergeordnete Verzeichnis des Makefiles. 
Wenn Sie beispielsweise cd /; make -f /home/username/project/Makefile ausführen, ist die Variable current_dir/ und nicht /home/username/project/.

Der folgende Code funktioniert für alle Makefiles, die aus einem beliebigen Verzeichnis aufgerufen werden:

mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path))))
206
Nikolai Popov

Wie von hier genommen;

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

Erscheint als;

$ cd /home/user/

$ make -f test/Makefile 
/home/user/test

$ cd test; make Makefile 
/home/user/test

Hoffe das hilft

108
sleepycal

Wenn Sie GNU make verwenden, ist $ (CURDIR) eine eingebaute Variable. Es ist der ort, an dem sich das Makefile befindetdas aktuelle Arbeitsverzeichnis, in dem sich das Makefile befindet, aber nicht immer.

OUTPUT_PATH = /project1/bin/$(notdir $(CURDIR))

Siehe Anhang A Kurzreferenz in http://www.gnu.org/software/make/manual/make.html

35
THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
22
momo

Ich habe viele dieser Antworten ausprobiert, aber auf meinem AIX-System mit gnu make 3.80 musste ich ein paar alte Dinge erledigen.

Stellt sich heraus, dass lastword, abspath und realpath erst in 3.81 hinzugefügt wurden. :(

mkfile_path := $(Word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
mkfile_dir:=$(Shell cd $(Shell dirname $(mkfile_path)); pwd)
current_dir:=$(notdir $(mkfile_dir))

Wie andere schon sagten, ist es nicht das eleganteste, da es zweimal eine Shell aufruft, und es gibt immer noch Probleme mit dem Speicherplatz.

Da ich jedoch keine Leerzeichen in meinen Pfaden habe, funktioniert es für mich unabhängig davon, wie ich make angefangen habe:

  • make -f ../wherever/makefile
  • machen -C ../wherever
  • -C ~/wo auch immer machen
  • cd ../wherever; machen

Alle geben mir wherever für current_dir und den absoluten Pfad zu wherever für mkfile_dir.

3
Jesse Chisholm

Die Lösung finden Sie hier: https://sourceforge.net/p/ipt-netflow/bugs-requests-patches/53/

Die Lösung lautet : $ (CURDIR)

Du kannst es so benutzen:

CUR_DIR = $(CURDIR)

## Start :
start:
    cd $(CUR_DIR)/path_to_folder
2
Soma Bini

Ich mag die gewählte Antwort, aber ich denke, es wäre hilfreicher, sie tatsächlich funktionieren zu lassen, als sie zu erklären.

/tmp/makefile_path_test.sh

#!/bin/bash -eu

# Create a testing dir
temp_dir=/tmp/makefile_path_test
proj_dir=$temp_dir/dir1/dir2/dir3
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)

all:
    @echo "MAKEFILE_LIST: $(MAKEFILE_LIST)"
    @echo "         path: $(path)"
    @echo "          cwd: $(cwd)"
    @echo ""
EOF

# See/debug each command
set -x

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

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

# Cleanup
rm -rf $temp_dir

Ausgabe:

+ cd /tmp/makefile_path_test/dir1/dir2/dir3
+ make
MAKEFILE_LIST:  Makefile
         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

HINWEIS: Mit der Funktion $(patsubst %/,%,[path/goes/here/]) wird der nachfolgende Schrägstrich entfernt.

2
Bruno Bronosky

Beispiel für Ihre Referenz wie folgt:

Die Ordnerstruktur könnte folgendermaßen lauten:

 enter image description here

Wo gibt es zwei Makefiles, jeweils wie unten;

sample/Makefile
test/Makefile

Lassen Sie uns nun den Inhalt der Makefiles sehen.

probe/Makefile

export ROOT_DIR=${PWD}

all:
    echo ${ROOT_DIR}
    $(MAKE) -C test

test/Makefile

all:
    echo ${ROOT_DIR}
    echo "make test ends here !"

Führen Sie nun das Sample/Makefile als aus.

cd sample
make

AUSGABE:

echo /home/symphony/sample
/home/symphony/sample
make -C test
make[1]: Entering directory `/home/symphony/sample/test'
echo /home/symphony/sample
/home/symphony/sample
echo "make test ends here !"
make test ends here !
make[1]: Leaving directory `/home/symphony/sample/test'

Eine Erklärung wäre, dass das übergeordnete/home-Verzeichnis im Umgebungsflag gespeichert und exportiert werden kann, sodass es in allen Unterverzeichnis-Makefiles verwendet werden kann.

0
parasrish

Hier ist ein Einzeiler, um den absoluten Pfad zu Ihrer Makefile-Datei mithilfe der Shell-Syntax abzurufen:

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

Und hier ist die Version ohne Shell basierend auf @ 0xff answer :

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

Testen Sie es, indem Sie es ausdrucken:

cwd:
        @echo $(CWD)
0
kenorb

Wenn die Variablen make den relativen Pfad enthalten, ist ROOT_DIR

ROOT_DIR := ../../../

Um den absoluten Pfad zu erhalten, verwenden Sie einfach die untenstehende Methode.

ROOT_DIR := $(abspath $(ROOT_DIR))

Seine Arbeit gut in GNUMake ...

0
Jerry

Tun Sie sich selbst einen großen Gefallen und erwarten Sie, dass jede make-Datei aus dem enthaltenen Verzeichnis ausgeführt wird. Sie müssen sich in keinem Befehl um irgendwelche Pfade kümmern.

0