Makefileを介してPATHにディレクトリを追加する


9

Makefile内で変更したPATHを現在のターミナルにエクスポートする際に問題が発生します。Makefileディレクトリがどこにあっても、PATH内のbinフォルダーに追加しようとしています。

makefileの関連するストリップは次のとおりです。

PATH := $(shell pwd)/bin:$(PATH)

install:
    mkdir -p ./bin 
    export PATH
    echo $(PATH)

エコーはそれを正しく出力しますが、ターミナルでエコーをやり直しても、PATHは同じままです。

回答:


16

あなたは単にこれを行うことはできません。makeプロセスが親の環境(または次に考えているかもしれない現在のディレクトリ)を変更できる方法はありません。

実際、あなたが思っているよりもずっと少ないことが起こっています。

  • すべてのmake実装PATHが環境内のmake 変数への割り当てを反映しているわけではありません。GNU make(Linuxや他のシステムで見つかる)にはありますが、BSD makeにはありません。
  • ターゲットの下の各コマンドラインは、個別のサブシェルで実行されます。(一部の古いBSD make実装を除きます。)そのため、そのexport PATH行はシェルで実行され、その後すぐに終了します。この行はそもそも何かをしているわけではありません— PATHその時点で定義されている場合、それはシェルの環境に既にあるからです。

Makeは自動的にビルドするためのものです。インタラクティブ環境に変数を設定したい場合、これは注目すべきツールではありません。代わりに、シェルスニペットを書き、ソース現在のシェルでそれを:

. ./define-my-variables.sh

メイクファイルで、すべてのサブシェルでスクリプトを入手します。バックスラッシュを使用して長いコマンドを作成できます。覚えて

  • バックスラッシュと改行のシーケンスはmakeによって取り除かれるので、シェルはそこに改行を認識しません。
  • それでも、各行の先頭にタブを付けることを忘れないでください。
  • Makeのエラー動作は、コマンドが失敗した場合に中止することです。シェルはデフォルトではこれを実行せず、コマンドの失敗はデフォルトで無視されます。そのため、を実行する必要がありますset -e
install:
    set -e; \
    . ./define-my-variables.sh; \
    mkdir -p bin; \
    …

¹ 義務的な注記:正気の道はありません。デバッガーからリモートで呼び出しchdirてもptrace、現在のディレクトリを自分の足元で変更したくないため、ほとんどのシェルではそのままでは機能しません。


えっと、「これは簡単に出来ない」は間違っていると思います。@Yeoの回答を参照してください:unix.stackexchange.com/a/291973/176350
XML

@XML Yeoの答えは、質問が要求するものとは異なる何かを行います。
Gilles「SO-邪悪なことをやめよう」

7

できません。サブプロセス(などmake)が親プロセスの環境を変更することはできません。

あなたは次のようなことができます

$ eval `make pathupdate`

どこにpathupdateターゲットルックスが好き:

pathupdate:
    @echo PATH=\"$(PATH)\"

6

あなたの答えはここにあります:https : //stackoverflow.com/a/8942216/367461

基本的に、これを行う必要があります:

export PATH := $(shell pwd)/bin:$(PATH)

test:
    mkdir -p ./bin
    @echo $(PATH)

私はこれをGNU Make 4.0を備えたFedora 23でテストしましたが、私には問題なく動作しました。


1
これはGNU Makeの正解です。BSDのメイクについては、使用することができます.SHELL: name=sh path=/path/to/wrapper-scriptし、その後のようなラッパースクリプトを作るexport FOO=bar; exec bash "$@"
RJH

2

他の回答例を機能させることができなかったので、これと同じ質問をします。

しかし、私はevalコマンドを使用することによって私のために実用的なソリューションを達成することができました。これが以前に投稿されなかった理由がよくわかりません。

do_something: 
    $(eval export PATH=$(shell pwd)/bin:$(PATH))
    @echo $(PATH)

注:PATH変更はmake自体の一時的なものです。makeを終了すると、PATHは以前の値にリセットされます。


これは、質問の内容ではないため、以前に投稿されていません。質問では、makeの終了後に変更されたPATHを取得する方法が質問されます。また、これははるかに簡単な方法で行うことができます:ラインに置くexport PATH=…と、do_something:必要ありませんeval
Gilles「SO-悪をやめる」

1

次のように、変更した環境でMakeを再帰的に呼び出すことができます。

dummy: build_all

all: 
    PATH=/new/directory:$(PATH) $(MAKE) build_all

build_all:
    your make rules 

シェルスニペットを使用する場合:

dummy: build_all

all:
    . ./define-my-variables.sh ; $(MAKE) build_all

build_all:
   your make rules
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.