Gcc aşağıdaki başlık dosyasını nasıl bulur?


8

Dahil ettim sys/ptrace.h C programıma.

Çıktısı /usr/lib/gcc/x86_64-linux-gnu/4.8/cc1 -v gcc'nin başlık dosyalarını aradığı aşağıdaki yolları verir

#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.

çıktısı gcc -M programım için aşağıdaki başlık dosya konumlarını verir

    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

Dan beri /usr/include/x86_64-linux-gnu/ ilk çıktıda yer almazsa, gcc nasıl bulur sys/ptrace.h?

DÜZENLE:

Çıktısı echo '#include <sys/ptrace.h>' | gcc -fsyntax-only -xc -v -H - sonuçlanır

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) 

Özyineyle bakıyor /usr/include.. Ne problemi çözmeye çalışıyorsun?
Ramhound

Özenle bakar gibi görünmüyor. Olsaydı, sys / prefix'in dahil edilmesine gerek kalmazdı. Örneğin sadece ptrace.h dahil, işe yaramaz.
user912083132

Dahil olduğunu sanmıyorum /sys/ptrace.h fakat sys/ptrace.h, sağ?
user20574

Bu neredeyse kesinlikle GCC'ye "multiarch" yamalarındaki bir hatadır. Rehber /usr/include/x86_64-linux-gnu olduğu Bir sistem olarak kabul edilir dizin ve meli tarafından basılan arama yolu listesine dahil edilebilir. gcc -v. Birinin bu hatayı nasıl başardığını bilemiyorum; doğru hatırlamıyorsam, sistem eklemenin en açık yolu dizinleri içerir. -v. (GCC'nin ön işlemcisinin ~% 50'sini yazdım, ancak bu 15 yıl önceydi, bu yüzden bir şeyi yanlış hatırlıyor olabilirim.)
zwol

@Ramhound Kesinlikle yapar değil aşağıda tekrarlı arama yapın /usr/include. Bu, dünyadaki hemen hemen her C kütüphanesini kıracaktı.
zwol

Yanıtlar:


8

Daha kısa cevap.

Sorunuz çıktı hakkında cc1 -v, ancak bu, CPP’de (C İşlemci Öncesi) bir etken değildir ve tüm derleme zincirine karıştırılmış olanları içerir. Eğer koşarsan cpp -v Sisteminizde görmeniz gereken, çıktısına benzer görünen bir içindekiler karışımıdır. cc1 -v ama en azından /usr/include/x86_64-linux-gnu orada yol eklendi.

Daha uzun cevap.

Dan beri /usr/include/x86_64-linux-gnu/ ilkinde yer almaz   çıktı, gcc nasıl bulur sys/ptrace.h?

Teknik olarak, /usr/include/x86_64-linux-gnu/ açıkça ilk çıktıda ayarlanmadı /usr/include/ kesinlikle öyle. Ve bu varsayılan bir arama yoludur Resmi GNU GCC belgelerinde açıklandığı gibi :

GCC başlıklar için birkaç farklı yere bakıyor. Normal bir Unix'te   Sistem, aksi belirtilmezse, başlıklar aranır.   ile istenen #include <file> içinde:

  • / Usr / yerel / bulunmaktadır
  • libdir / gcc / hedef / sürüm / include
  • / Usr / hedef / bulunmaktadır
  • / Usr / include

Ve ayrıca burada açıkladı:

GCC, talep edilen başlıkları arıyor #include "file" ilk olarak   Geçerli dosyayı içeren dizin, ardından dizinlerde olduğu gibi   tarafından belirtilen -iquote seçenekler, sonra aynı yerlerde olurdu   Açılı ayraçlarla istenen bir başlık aradı. Örneğin, eğer /usr/include/sys/stat.h # içerir include "types.h", GCC arar types.h ilk önce /usr/include/sys, sonra her zamanki gibi arama yolunda.

Yani bu demek oluyor ki x86_64-linux-gnu/ yol basit bir şekilde eklenir /usr/include/*/sys/ bunun gibi:

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

En azından başlangıçta düşündüğüm şey bu. bu sorunun daha eski bir sürümü . Fakat bu siteyi kontrol ettikten sonra olup bitenlerin açıklaması biraz daha ayrıntılıdır ve bu siteden yukarıda yayınladıklarımın eşdeğer içeriğine doğrudan cevap aşağıda verilmiştir; cesur vurgu benimdir:

ama bu bir nezaket-cevapsız cevap (ve aynı zamanda eksik). elbette   GCC'nin size tam olarak nereye gideceğini söylemesini sağlamanın bir yolu olmalı   sonunda başlık dosyalarını mı arıyorsunuz? Her ne kadar uygun olsa da   GCC'yi alan tek bir monolitik uygulama olarak düşünmek   kaynak kodu dosyaları ve çalışma programları tükürür, teknik olarak bir   birlikte üretmek için zincir oluşturan diğer programların toplanması   derlenmiş nesne dosyası. Bunlardan ilki CPP’dir, C   Ön İşlemci , kimin işi gibi derleyici direktifleri aramaktır #include ve kaynak kodunu, kendileri tarafından belirlenen şekilde değiştirin; Dahil olması durumunda, başka bir dosyanın içeriğini geçerli alana kopyalayarak   bir. Bu dosyaları nerede aradığını görebilirsiniz -v   bayrak:

CPP'nin (C Ön İşlemci) derleyicinin işlemindeki ilk adım olduğunu bilin. cpp -v Ubuntu 12.04.5 test sistemimde:

#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

Orada açıkça görebilirsiniz /usr/include/x86_64-linux-gnu. Ve karşılaştırmak için, işte benzer "dahil" çıktısıdır. /usr/lib/gcc/x86_64-linux-gnu/4.6/cc1 -v aynı Ubuntu 12.04.5 test sisteminde:

#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

Nasıl not /usr/include/x86_64-linux-gnu ilk CPP (C İşlemci Öncesi) işlemi ile karışıma açıkça eklenir. Ve bu sitedeki posta bu yolların nereden geldiğini açıklamak için devam ediyor; tekrar cesur vurgu benim:

bu yol aslında derleme zamanında CPP'ye (ki GCC'nin bir parçası) inşa edilmiştir; eğer ne sebeple olursa olsun bunlardan birini silmeye kalkarsanız   dizinler, her derleme için yine de kontrol edilecektir. Her   burada listelenen sırayla dizin aranır; eğer bir dosya   içinde bulunan /usr/local/include, sonraki üç dizin olmayacak   kontrol.

Böylece hepsi bir C derleme zincirinin ilk parçası olarak adlandırılan CPP'ye (C Ön İşlemci) kadar kaynıyor.


Neden x86_64-linux-gnu / ortasına doğru itiliyor?
user912083132

@ user912083132: İşte bu $TARGET cevap ve yorumumda bahsettiğim bölüm. Bu çıktısı config.guess GCC derlendiğinde veya hangisine configure komut dosyasıyla --target bayrağı. Asıl soru, bu yol nasıl birleştirilir? Sadece aynı listeye geri dönüyor mu? $TARGET Her birine, başlığını ilk kez bulamadı mı?
Warren Young

@ user912083132 Bazı yeni toplanmış bilgilerle cevabımı güncelledim. Lütfen tekrar okuyunuz; Cevap, CPP'den (C Ön İşlemci) geldiğini açıklıyor.
JakeGould

2

GCC kaynak koduna girmeden, size bir "neden" veremem, ancak size burada sahip olduğum GCC sürümünün geri döndüğünü söyleyebilirim /usr/include/$TARGET seçimlerinizi tükettikten sonra ve JakeGould bulduk . Öyle görebilirsin:

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

nerede foo.c içerir #include <sys/ptrace.h>.

İhtiyacın var -f Burada tartışma çünkü gcc Gerçek derleme işini yapmak için çocukları doğurur. İhtiyacın var 2>&1 Çünkü strace sonuçlarını stdout'a değil stderr'e yazıyor.

Dikkat edin ENOENT sonunda başarılı olanı denemeden önce belgelenen tüm dizinler için hatalar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.