मैं मेकफाइल में $ PATH में dir कैसे जोड़ सकता हूं?


87

मैं एक मेकफाइल लिखना चाहता हूं जो परीक्षण चलाएगा। परीक्षण एक निर्देशिका './tests' में हैं और परीक्षण की जाने वाली निष्पादन योग्य फाइलें निर्देशिका './bin' में हैं।

जब मैं परीक्षण चलाता हूं, तो वे निष्पादन फ़ाइलों को निर्देशिका के रूप में नहीं देखते हैं ।/bin $ PATH में नहीं है।

जब मैं ऐसा कुछ करता हूं:

EXPORT PATH=bin:$PATH
make test

सब कुछ काम करता है। हालाँकि मुझे मेकफाइल में $ PATH को बदलना होगा।

सरल मेकफाइल सामग्री:

test all:
    PATH=bin:${PATH}
    @echo $(PATH)
    x

यह पथ को सही ढंग से प्रिंट करता है, हालांकि यह फ़ाइल x को नहीं खोजता है।

जब मैं इसे मैन्युअल रूप से करता हूं:

$ export PATH=bin:$PATH
$ x

सब कुछ ठीक है।

मैं मेकफाइल में $ PATH को कैसे बदल सकता हूं?


क्या आप परीक्षण को निष्पादन योग्य निर्देशिका से नहीं बुला सकते हैं ../test/test_to_run? क्षमा करें, यदि मैंने प्रश्न को गलत समझा है।
क्रिस

मैं चाहता हूं कि यह फाइल सामान्य रूप से परीक्षण के लिए दिखाई दे। मैं निर्देशिकाओं के साथ नहीं खेलना चाहता, क्योंकि मैं यह दर्शाता हूं कि एक निगमेअर होगा।
सिजमन लिपिस्की

जिस तरह से आप इसके करीब आ सकते हैं, वह यह है कि मेकफाइल में एक शेल स्क्रिप्ट होती है जिसमें वेरिएबल डिकल्स होते हैं और फिर उस स्क्रिप्ट के मूल शैल स्रोत होते हैं .। यह संभवत: अव्यवहारिक है।
माइकल स्मिथ

मेरा मानना ​​है कि unix.stackexchange.com/questions/11530/… एक बहुत ही अलग (बेवकूफ) सवाल है, आपके विपरीत।
इम्ज़ - इवान ज़खरीशेव

जवाबों:


106

क्या आपने खुद मेक के exportनिर्देशन की कोशिश की (यह मानते हुए कि आप GNU मेक का उपयोग करते हैं)?

export PATH := bin:$(PATH)

test all:
    x

इसके अलावा, आपके उदाहरण में एक बग है:

test all:
    PATH=bin:${PATH}
    @echo $(PATH)
    x

सबसे पहले, echoएड होने वाला मूल्य PATHमेक द्वारा निष्पादित चर का विस्तार है , न कि शेल। अगर यह अपेक्षित मूल्य को प्रिंट करता है, तो मुझे लगता है, आपने PATHअपने मेकफाइल में पहले से कहीं चर स्थापित किया है , या मेक को लागू करने वाले शेल में। इस तरह के व्यवहार को रोकने के लिए आपको डॉलर से बचना चाहिए:

test all:
    PATH=bin:$$PATH
    @echo $$PATH
    x

दूसरे, किसी भी मामले में यह काम नहीं करेगा क्योंकि मेक नुस्खा की प्रत्येक पंक्ति को एक अलग शेल में निष्पादित करता है । इसे एकल पंक्ति में नुस्खा लिखकर बदला जा सकता है:

test all:
    export PATH=bin:$$PATH; echo $$PATH; x

7
$(PATH)PATHशेल बनाने के मूल्य के लिए सेट हो जाएगा । मैनुअल के अनुसार , "प्रत्येक पर्यावरण चर जो बनाता है जब देखता है कि यह एक ही नाम और मूल्य के साथ एक परिवर्तनशील चर में बदल जाता है।"
एमिल बैठ

निर्यात निर्देशन ने मेरे लिए काम किया (धन्यवाद!), लेकिन उसके बाद ही मैंने जीएनयू मेक 4.3 स्थापित किया। संस्करण 3.81 (MacOS कैटालिना पर डिफ़ॉल्ट) में, अपडेट PATHसही ढंग से चर (में दिखाई देता है echo $(PATH)) और आदेश 'वातावरण (भीतर env, which python, bash -c python), लेकिन जब आदेश के लिए निष्पादन योग्य लगाने में इस्तेमाल किया जा प्रतीत नहीं होता है: आदेश pythonअभी भी चलाता है मूल पर पायथन निष्पादन योग्य PATH
doctaphred

27

डिज़ाइन makeपार्सर द्वारा एक अलग शेल इनवोकेशन में लाइनों को निष्पादित किया जाता है, इसीलिए PATHएक लाइन में परिवर्तनशील (जैसे ), अगली लाइनों के लिए परिवर्तन लागू नहीं हो सकता है (यह पोस्ट देखें )।

इस समस्या को हल करने का एक तरीका, एकाधिक कमांड्स को एक लाइन (अलग से ;) में बदलना या वन शैल स्पेशल टारगेट ( .ONESHELL, GNU मेक 3.82 के रूप में) का उपयोग करना है।

वैकल्पिक रूप से आप PATHउस समय चर प्रदान कर सकते हैं जब शेल को लगाया जाता है। उदाहरण के लिए:

PATH  := $(PATH):$(PWD)/bin:/my/other/path
SHELL := env PATH=$(PATH) /bin/bash

2
मुझे दृष्टिकोण पसंद है!
एलन फ्रांजोनी

2
यह सबसे अच्छा है, क्योंकि यह $(shell)इनवोकेशन के साथ भी काम करता है ! : D उदाहरण: pastebin.com/Pii8pmkD
PsychoX

Dev.azure पर मुझे मिलता है: env: 'env': ऐसी कोई फ़ाइल या निर्देशिका नहीं; स्थानीय रूप से काम करता है; /
कामिल डिजिडिक

डेबियन 10 पर 4.2 बनाने के साथ काम नहीं करता है: Make: env PATH = <path> / bin / sh: कमांड नहीं मिला। निर्यात कार्यों का उपयोग करना। घर डायर में एक पथ के लिए $ (गृह) और न ~ का उपयोग करना सुनिश्चित करें।
MKesper

25

यदि आप पहले अपने मेकफाइल में शेल परिवर्तन सेट करते हैं, तो पथ परिवर्तन लगातार दिखाई देते हैं:

SHELL := /bin/bash
PATH := bin:$(PATH)

test all:
    x

मुझे नहीं पता कि यह वांछित व्यवहार है या नहीं।


इससे मुझे होने वाली समस्या ठीक हो गई (मैं zsh चला रहा हूँ)। धन्यवाद!
जेजेन थॉमस

हाँ, यह वास्तव में वही करता है जो ओपी चाहता था ... लेकिन क्या यह एक विशेषता या बग है? मेक मैनुअल के शेल अनुभाग को पढ़ने के बाद भी मुझे यकीन नहीं है।
पीजे

5
यह मेरे लिए भी काम नहीं करता है। whichऔर envअब नए PATH को उठाएं, लेकिन बाइनरी को सीधे निष्पादित करना अभी भी संशोधित PATH में नहीं मिला है, केवल मूल में।
कोनराड रूडोल्फ

3

मैं आमतौर पर निष्पादन योग्य पथ को स्पष्ट रूप से आपूर्ति करता हूं:

EXE=./bin/
...
test all:
    $(EXE)x

मैं इस तकनीक का उपयोग QEMU जैसे एमुलेटर के तहत गैर-देशी बायनेरिज़ को चलाने के लिए करता हूं अगर मैं क्रॉस संकलन कर रहा हूं:

EXE = qemu-mips ./bin/

यदि शेल शेल का उपयोग किया जाता है, तो यह काम करना चाहिए:

test all:
    PATH=bin:$PATH x

हां, शांत आत्मा है, हालांकि मुझे अपने परीक्षण पर्ल में लिखे गए हैं और मुझे सीधे पर्ल से स्क्रिप्ट को कॉल करने की आवश्यकता है, न कि सीधे मेकफाइल से। मुझे इस सामान के पूरे परीक्षण पर पुनर्विचार करना है :)
सिजमन लिपिस्की

पकड़ लिया। कमांड लाइन पर PATH की स्थापना कैसे करें? ऊपर संपादित देखें।
रिचर्ड पेनिंगटन

-2

PATHवैरिएबल सेट करने के लिए , Makefile के भीतर ही, कुछ इस तरह का उपयोग करें:

PATH := $(PATH):/my/dir

test:
@echo my new PATH = $(PATH)

यह मेरे इच्छित तरीके से काम नहीं करता है। मैंने प्रश्न को अद्यतन किया है कि मैं क्या हासिल करना चाहता हूं।
सिजमन लिपिस्की
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.