Gcc निम्नलिखित हेडर फ़ाइल को कैसे खोजता है?


10

मैंने sys/ptrace.hअपने C प्रोग्राम में शामिल किया है।

/usr/lib/gcc/x86_64-linux-gnu/4.8/cc1 -vनिम्न पथों का आउटपुट देता है जहाँ शीर्षलेख फ़ाइलों के लिए gcc दिखता है

#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed
 /usr/include
End of search list.

gcc -Mमेरे प्रोग्राम का आउटपुट निम्न हेडर फ़ाइल स्थान देता है

    pt.o: pt.c /usr/include/stdc-predef.h /usr/include/stdio.h \
 /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \
 /usr/include/x86_64-linux-gnu/bits/wordsize.h \
 /usr/include/x86_64-linux-gnu/gnu/stubs.h \
 /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \
 /usr/include/x86_64-linux-gnu/bits/types.h \
 /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \
 /usr/include/_G_config.h /usr/include/wchar.h \
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \
 /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \
 /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \
 /usr/include/x86_64-linux-gnu/sys/ptrace.h

चूँकि /usr/include/x86_64-linux-gnu/पहले आउटपुट में समाहित नहीं है, तो gcc कैसे पता करता है sys/ptrace.h?

संपादित करें:

में echo '#include <sys/ptrace.h>' | gcc -fsyntax-only -xc -v -H -परिणाम का उत्पादन

Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-2ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04) 

यह पुनरावृत्ति को देख रहा है /usr/include.. आप किस समस्या को हल करने की कोशिश कर रहे हैं?
रामहाउंड

ऐसा नहीं लगता कि यह पुनरावर्ती रूप से दिखता है। यदि यह किया जाता है, तो sys / उपसर्ग को शामिल करने की कोई आवश्यकता नहीं होगी। उदाहरण के लिए, केवल ptrace.h को शामिल करना, काम नहीं करता है।
user912083132

मुझे नहीं लगता कि आपने इसे शामिल किया है , /sys/ptrace.hलेकिन sys/ptrace.hठीक है?
user253751

यह लगभग निश्चित रूप से जीसीसी को "मल्टीकार" पैच में एक बग है। निर्देशिका /usr/include/x86_64-linux-gnu है इलाज किया जा रहा के रूप में एक प्रणाली निर्देशिका में शामिल हैं और चाहिए खोज पथ सूची द्वारा मुद्रित में शामिल किया gcc -v। मुझे यकीन नहीं है कि कोई उस बग को हासिल करने में कैसे कामयाब रहा; अगर मुझे सही ढंग से याद है, तो सिस्टम को जोड़ने का सबसे स्पष्ट तरीका निर्देशिकाओं में शामिल है जो उन्हें मुद्रित करता है -v। (मैंने लिखा है ~ जीसीसी के प्रीप्रोसेसर का ५०%, लेकिन वह १५ साल पहले था, इसलिए मुझे कुछ गलत हो रहा होगा।)
२३:०३ पर zwol

@ रामहाउंड यह निश्चित रूप से नीचे पुनरावर्ती खोज नहीं करता है /usr/include। यह दुनिया के हर सी लाइब्रेरी के बारे में बताएगा।
zwol

जवाबों:


12

छोटा जवाब।

आपका प्रश्न आउटपुट के बारे में है cc1 -v, लेकिन यह CPP (C Pre-Processor) का कारक नहीं है और इसमें संपूर्ण संकलन श्रृंखला में शामिल किए गए हैं। यदि आप cpp -vअपने सिस्टम पर चलते हैं तो आपको देखना चाहिए, इसमें एक मिश्रण शामिल है जो आउटपुट के समान दिखता है, cc1 -vलेकिन कम से कम /usr/include/x86_64-linux-gnuपथ को इसमें जोड़ा गया है।

लंबा जवाब।

चूँकि /usr/include/x86_64-linux-gnu/पहले आउटपुट में समाहित नहीं है, तो gcc कैसे पता करता है sys/ptrace.h?

तकनीकी रूप से, /usr/include/x86_64-linux-gnu/पहले आउटपुट में स्पष्ट रूप से सेट नहीं है, लेकिन /usr/include/निश्चित रूप से है। और यह एक डिफ़ॉल्ट खोज पथ है जैसा कि आधिकारिक GNU GCC प्रलेखन में बताया गया है :

जीसीसी हेडर के लिए कई अलग-अलग जगहों पर दिखता है। एक सामान्य यूनिक्स प्रणाली पर, यदि आप इसे अन्यथा निर्देश नहीं देते हैं, तो इसके साथ अनुरोध किए #include <file>गए हेडर की तलाश करेंगे :

  • / Usr / स्थानीय / शामिल
  • libdir / जीसीसी / लक्ष्य / संस्करण / शामिल
  • / Usr / लक्ष्य / शामिल
  • / Usr / शामिल

और आगे यहाँ बताया गया है:

जीसीसी #include "file"वर्तमान फ़ाइल वाले निर्देशिका में पहले अनुरोध किए गए हेडर की तलाश करता है -iquote, फिर विकल्पों द्वारा निर्दिष्ट निर्देशिकाओं में , फिर उन्हीं स्थानों में कोण कोष्ठक के साथ अनुरोध किए गए हेडर की तलाश होती। उदाहरण के लिए, यदि /usr/include/sys/stat.h# शामिल है , तो include "types.h"जीसीसी types.hपहली बार में दिखता है /usr/include/sys, फिर अपने सामान्य खोज पथ में।

तो इसका तात्पर्य यह है कि x86_64-linux-gnu/रास्ता बस /usr/include/*/sys/इस तरह से डाला गया है:

/usr/include/x86_64-linux-gnu/sys/ptrace.h

कम से कम यही वह है जो मैंने शुरू में इस सवाल के एक पुराने संस्करण में सोचा था । लेकिन इस साइट की जाँच करने के बाद कि क्या हो रहा है, इसका विवरण थोड़ा और विस्तृत है और उस साइट से जो मैंने ऊपर पोस्ट किया है उसके बराबर सामग्री के लिए सीधी प्रतिक्रिया नीचे दी गई है; बोल्ड जोर मेरा है:

लेकिन यह एक इच्छाधारी-धोबी का जवाब है (और अपूर्ण भी)। निश्चित रूप से जीसीसी को प्राप्त करने का एक तरीका होना चाहिए ताकि आपको यह बताया जा सके कि इसकी हेडर फ़ाइलों की तलाश कहां खत्म हो रही है? खैर, हालांकि यह एक एकल अखंड एप्लिकेशन के रूप में जीसीसी के बारे में सोचना सुविधाजनक है जो स्रोत कोड फ़ाइलों में लेता है और काम कर रहे कार्यक्रमों को बाहर निकालता है, यह तकनीकी रूप से अन्य कार्यक्रमों का एक संग्रह है जो अंतिम संकलित वस्तु फ़ाइल का उत्पादन करने के लिए एक साथ श्रृंखला बनाते हैं। इनमें से पहला सीपीपी है, सी प्री-प्रोसेसर के लिए छोटा है , जिसका काम संकलक निर्देशों की तरह देखना #includeऔर उनके द्वारा निर्दिष्ट स्रोत कोड को संशोधित करना है; वर्तमान फ़ाइल में किसी अन्य फ़ाइल की सामग्री की प्रतिलिपि बनाकर शामिल करें। आप यह देख सकते हैं कि यह इन फ़ाइलों को -v झंडा पास करके कहाँ दिखता है:

जान लें कि सीपीपी (सी प्री-प्रोसेसर) कंपाइलर की प्रक्रिया का पहला चरण है, आइए cpp -vमेरे Ubuntu 12.04.5 परीक्षण प्रणाली के "शामिल" आउटपुट को देखें :

#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/4.6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include

वहां आप स्पष्ट रूप से देख सकते हैं /usr/include/x86_64-linux-gnu। और तुलना करने के लिए, यहां एक /usr/lib/gcc/x86_64-linux-gnu/4.6/cc1 -vही Ubuntu 12.04.5 परीक्षण प्रणाली पर समान "शामिल" आउटपुट है:

#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/4.6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed
 /usr/include

ध्यान दें कि /usr/include/x86_64-linux-gnuप्रारंभिक सीपीपी (सी प्री-प्रोसेसर) कार्रवाई द्वारा मिश्रण में स्पष्ट रूप से कैसे डाला जाता है। और उस साइट पर पोस्ट आगे बताती है कि वे रास्ते कहाँ से आते हैं; फिर से बोल्ड जोर मेरा है:

यह पथ वास्तव में संकलन समय पर सीपीपी (जो जीसीसी का हिस्सा है) में बनाया गया है; यदि किसी भी कारण से आप उन निर्देशिकाओं में से एक को हटा रहे हैं, तो यह अभी भी प्रत्येक संकलन के लिए जाँच की जाएगी। प्रत्येक निर्देशिका को उस क्रम में खोजा जाता है, जो यहाँ सूचीबद्ध है; यदि कोई फ़ाइल मिलती है /usr/local/include, तो अगली तीन निर्देशिकाओं की जाँच नहीं की जाएगी।

इसलिए यह सभी CPP (C Pre-Processor) पर उबलता है जिसे C संकलन श्रृंखला का पहला भाग कहा जाता है।


X86_64-linux-gnu / मध्य में क्यों चमकता है?
user912083132

@ user912083132: यह वह $TARGETहिस्सा है जिसका मैंने अपने उत्तर और टिप्पणी में उल्लेख किया है। यह तब का आउटपुट है config.guessजब जीसीसी संकलित किया गया था, या जिसे इसकी configureस्क्रिप्ट को --targetध्वज के साथ दिया गया था । असली सवाल यह है कि वह रास्ता कैसे इकट्ठा हो जाता है? क्या यह केवल एक ही सूची के माध्यम से वापस जाता है, $TARGETप्रत्येक को जोड़कर , हेडर को पहली बार खोजने में विफल होने के बाद?
वॉरेन यंग

@ user912083132 कुछ नई जानकारी के साथ मेरे उत्तर अपडेट करें। कृपया इसे फिर से पढ़ें; उत्तर बताते हैं कि यह सीपीपी (सी प्री-प्रोसेसर) से आता है।
जेकगॉल्ड

2

जीसीसी स्रोत कोड में देरी से, मैं आपको "क्यों" नहीं दे सकता, लेकिन मैं आपको बता सकता हूं कि /usr/include/$TARGETआपके और जेकगोल्ड के विकल्पों को समाप्त करने के बाद जीसीसी I का संस्करण यहां वापस आ गया है । आप इसे इस तरह देख सकते हैं:

$ strace -f -e open gcc -c foo.c -o foo.o 2>&1 | grep ptrace.h

जहां foo.cएक होता है #include <sys/ptrace.h>

आपको -fयहां तर्क की आवश्यकता है क्योंकि gccबच्चों को वास्तविक संकलन कार्य करने के लिए प्रेरित करता है। आपको इसकी आवश्यकता है 2>&1क्योंकि stracestderr को इसके परिणाम लिख रहे हैं, stdout को नहीं।

ध्यान दें कि आप ENOENTसभी प्रलेखित निर्देशिकाओं के लिए त्रुटियां प्राप्त करते हैं, इससे पहले कि वह सफल हो जाए।

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