जीएनयू/मैनुअल बनाने §5.7 जीएनयू/बनाने बनाने के लिए कहा गया है निम्नलिखित:रोक निर्देशिका के सांकेतिक लिंक de-संदर्भित
5,7 की रिकर्सिव उपयोग
मेकअप की रिकर्सिव उपयोग के रूप में बनाने का उपयोग कर का मतलब कर एक मेकफ़ाइल में एक कमांड। यह तकनीक तब उपयोगी होती है जब आप विभिन्न सबसिस्टम के लिए अलग मेकफ़ाइल चाहते हैं जो एक बड़ी प्रणाली लिखते हैं। उदाहरण के लिए, मान लें कि आपके पास एक उपनिर्देशिका उपदिर है जिसका अपना स्वयं का मेकफ़ाइल है, और आप उपनिर्देशिका पर चलाने के लिए युक्त निर्देशिका की मेकफ़ाइल चाहते हैं। आप इस लिख कर यह कर सकते हैं:
subsystem: cd subdir && $(MAKE) or, equivalently, this (see Summary of Options): subsystem: $(MAKE) -C subdir
तो, मूल रूप से यह संकेत मिलता है कि cd subdir && $(MAKE)
$(MAKE) -C subdir
के समान है।
हालांकि, यह पता चला है कि यह वास्तव में समकक्ष नहीं है। -C
विकल्प का उपयोग करते समय, निर्देशिका पथ, यदि यह एक सिम्लिंक है, तो हमेशा डी-रेफरेंस किया जाता है, इसलिए "लॉजिकल" (pwd -L
में) निर्देशिका नाम प्राप्त करने का कोई तरीका नहीं है। निम्नलिखित उदाहरण पर विचार करें। निम्नलिखित Makefile
में /tmp/b
निर्देशिका, जो /tmp/a/
निर्देशिका में एक सिमलिंक है बीत रहा है:
foo:
@echo PWDL=$(shell pwd -L)
@echo PWDP=$(shell pwd -P)
@echo CURDIR=$(CURDIR)
अब, चलो make
अलग ढंग से आह्वान करते हैं:
$ pwd
/tmp
$ (cd b && make foo)
PWDL=/tmp/b
PWDP=/tmp/a
CURDIR=/tmp/a
$ make -C b foo
make: Entering directory `/tmp/a'
PWDL=/tmp/a
PWDP=/tmp/a
CURDIR=/tmp/a
make: Leaving directory `/tmp/a'
$ make --directory=b foo
make: Entering directory `/tmp/a'
PWDL=/tmp/a
PWDP=/tmp/a
CURDIR=/tmp/a
make: Leaving directory `/tmp/a'
$
आप देख सकते हैं, pwd -P
और $(CURDIR)
हमेशा डे दिखा रहे हैं संदर्भित प्रतीकात्मक लिंक। लेकिन pwd -L
केवल make
चलाने से पहले निर्देशिका को बदलते समय काम करता है, जो साबित करता है कि -C
विकल्प जीएनयू/विकल्प हमेशा किसी भी अच्छे कारण के लिए निर्देशिका पथ को संदर्भित नहीं करता है। मैं दस्तावेज में इस व्यवहार के लिए कोई स्पष्टीकरण खोजने की कोशिश कर रहा था लेकिन नहीं कर सका। make
(या w/o बहुत खराब हुक ट्रॉफ़ LD_PRELOAD
) चलाने से पहले cd
का उपयोग करके निर्देशिका को बदले बिना मैं इस समस्या के लिए एक समाधान के साथ आ सकता हूं।
सवाल यह है कि - क्या कोई और इस समस्या में पहले भाग लेता है, स्पष्टीकरण या कामकाज करता है? धन्यवाद!
अद्यतन:
यह की तह तक पहुंचने की कोशिश कर रहा है, मैं make
के लिए स्रोत कोड डाउनलोड किया है और निर्देशिका के किसी विशेष प्रसंस्करण नहीं मिला, केवल chdir
को कहता है। इसलिए मैंने एक प्रयोग करने के लिए एक छोटा सा कार्यक्रम लिखा, और यहां मुझे जो मिला वह है।
जब आप एक सिम्लिंक निर्देशिका (/tmp/b
) में होते हैं और निर्देशिका को बदलने की कोशिश करते हैं, तो ऑपरेशन का कोई प्रभाव नहीं पड़ता है और वर्तमान कार्यशील निर्देशिका प्रतीकात्मक लिंक को इंगित करती रहती है।
जब आप chdir()
पर कॉल करते हैं और या तो पूर्ण या सापेक्ष पथ निर्दिष्ट करते हैं, तो यह निर्देशिका को बदलने से पहले इसे संदर्भित करता है। यहाँ है एक साबित:
$ cat cd.cpp
#include <stdio.h>
#include <unistd.h>
int main()
{
chdir ("/tmp/b/");
printf ("Current dir: %s\n",
get_current_dir_name()); /* Forgive my memory leak. */
}
$ gcc -o test ./cd.cpp
$ pwd
/tmp/b
$ ./test
Current dir: /tmp/b
$ cd ../
$ ./b/test
Current dir: /tmp/a
$ cd/
$ /tmp/b/test
Current dir: /tmp/a
$
तो यह या तो libc
या लिनक्स मुझ पर चालें खेल रहा है कि मैं वास्तव में के बारे में पहले ध्यान नहीं दिया की तरह लगता है।और उसके शीर्ष पर, s
सीडी` किसी भी तरह से काम कर रहा है।
आश्चर्यजनक रूप से पर्याप्त, Linux chdir()
man page इसके बारे में कुछ भी उल्लेख नहीं करता है, लेकिन बोर्लैंड बिल्डर (! एसआईसी) दस्तावेज, here में इसके बारे में एक नोट है। तो मुझे आश्चर्य है कि bash
इस संबंध में क्या करता है।
यह वह व्यवहार है जिसे मैं वास्तव में बनाने की अपेक्षा करता हूं। "तार्किक" निर्देशिका पूरी तरह से खोल द्वारा एक आविष्कार है, जो भ्रम को बनाए रखने के लिए अतिरिक्त काम करता है। – ephemient
@ephemient: मैंने सोचा कि यह ऐसा कुछ कर रहा है, लेकिन अजीब बात यह है कि, 'सीडी' करते समय और 'getcwd()', 'getcwd()' को कॉल करने वाली प्रक्रिया का आह्वान करते हुए, symlink के लिए पथ देता है, न कि वास्तविक निर्देशिका। मैंने symlink के पूर्ण पथ के साथ 'chdir()' को कॉल करने का प्रयास किया है और उसी प्रभाव को प्राप्त नहीं कर सकता है। मैं सोच रहा हूं कि वास्तव में क्या चल रहा है। –
'bash'' $ PWD' में कार्यरत निर्देशिका को कैश करता है। खोल अपडेट में 'सीडी' '$ पीडब्ल्यूडी'। शैल रिटर्न में 'pwd' '$ PWD' अगर यह वास्तविक कार्य निर्देशिका से मेल खाता है। जब आप 'cd && $ (MAKE)' का उपयोग करते हैं, तो चर आवर्ती आमंत्रण के लिए सेट किया जाता है; जब आप '$ (MAKE) -C' का उपयोग करते हैं, तो यह नहीं है, और 'pwd' अनचाहे भौतिक पथ पर वापस आ जाता है। – ephemient