2011-07-13 23 views
25

Bir meslektaşım, kısa bir süre önce, derleme sırasında tek bir kaynak dosyamızın 3,400'ün üzerinde başlık içerdiğini bana gösterdi. Bir derlemede derlenen 1000'den fazla çeviri birimimiz var. Bu, kesinlikle kullanılmayan başlıkların üzerinde büyük bir performans cezasıyla sonuçlanıyor.Başlık dosyası dahil etme statik analiz araçları?

Böyle bir ormandaki ağaçlara ışık tutabilecek herhangi bir statik analiz aracı var mıdır, özellikle de hangilerinin ayrıştırılması için üzerinde çalışmamız gerektiğine karar vermemiz mümkün mü?

GÜNCELLEME bir başlık dosyası dahil maliyeti bazı ilginç bilgiler bulundu

this question itibaren here menşeli (ve türlerini alınması yönünde optimize etmek korumaları dahil).

+0

Hangi platformdasınız? gcc, bu konuda yardımcı olabilecek seçeneklere sahiptir (hiç kimse daha iyi bir fikir önermezse) – Nemo

+0

@Nemo: Hem gcc hem de MSVC. – fbrereto

+0

http://stackoverflow.com/questions/42308/tool-to-track-include-dependencies – jfritz42

cevap

23

gcc -w -H <file> çıktısı yararlı olabilir (Ayrıştırırsanız ve bazı sayımlar yaparsanız), -w, tüm uyarıları bastırmak için oradadır, bu da başa çıkmak zor olabilir. gcc Dokümanlar

:

-H

Baskı diğer normal aktivitelere ek olarak, kullanılan her başlık dosyasının adı. Her isim, #include yığınının ne kadar derin olduğunu göstermek için girintilidir. Önceden derlenmiş üstbilgi dosyaları da geçersiz oldukları halde bile yazdırılır; Önceden geçersiz bir üstbilgi dosya ...x ve ...! ile geçerli bir tane yazdırılır.

çıktı şuna benzer: şeyler-

. /usr/include/unistd.h 
.. /usr/include/features.h 
... /usr/include/bits/predefs.h 
... /usr/include/sys/cdefs.h 
.... /usr/include/bits/wordsize.h 
... /usr/include/gnu/stubs.h 
.... /usr/include/bits/wordsize.h 
.... /usr/include/gnu/stubs-64.h 
.. /usr/include/bits/posix_opt.h 
.. /usr/include/bits/environments.h 
... /usr/include/bits/wordsize.h 
.. /usr/include/bits/types.h 
... /usr/include/bits/wordsize.h 
... /usr/include/bits/typesizes.h 
.. /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/include/stddef.h 
.. /usr/include/bits/confname.h 
.. /usr/include/getopt.h 
. /usr/include/stdio.h 
.. /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/include/stddef.h 
.. /usr/include/libio.h 
... /usr/include/_G_config.h 
.... /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/include/stddef.h 
.... /usr/include/wchar.h 
... /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/include/stdarg.h 
.. /usr/include/bits/stdio_lim.h 
.. /usr/include/bits/sys_errlist.h 
Multiple include guards may be useful for: 
/usr/include/bits/confname.h 
/usr/include/bits/environments.h 
/usr/include/bits/predefs.h 
/usr/include/bits/stdio_lim.h 
/usr/include/bits/sys_errlist.h 
/usr/include/bits/typesizes.h 
/usr/include/gnu/stubs-64.h 
/usr/include/gnu/stubs.h 
/usr/include/wchar.h 
+0

'dan nereden geldiğini bulmak için çok yararlı değil devenv/msvs için benzer bir şey var mı? – andreas

+0

@ user375251 Bilmiyorum, bir şey için MS araç zincirini kullanmayın, MSDN – Spudd86

+0

@ Spudd86 seçeneğini işaretleyin, -H seçeneği ile her dosya adını manuel olarak yazmadan projedeki her dosya için bu tür bir içeriğe sahip olabilir miyim? – Alecs

3

Eğer gcc/g ++ kullanıyorsanız, -M or -MM option aradığınız bilgi ile bir satır çıkartacaktır.

$ gcc -M -c foo.c 
foo.o: foo.c /usr/include/stdint.h /usr/include/features.h \ 
    /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \ 
    /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \ 
    /usr/include/bits/wchar.h 

Sen başında foo.o: foo.c kaldırmak gerekir, ama geri kalan tüm başlıkların listesidir; (. Bkz kılavuzu. İkincisi diğer değişken vardır olmaz ise eski sistem başlıklarını içerecektir) Dosyaya bağlı olduğu için, bunları toplamak ve özetlemek için bir senaryo yazmak çok zor olmaz.

Elbette bu öneri sadece Unix'te ve başka hiç kimsenin daha iyi bir fikri olmadığı durumlarda kullanışlıdır.

+1

tüm içeriklerini – Spudd86

1

GCC, belirli bir kaynak dosya için bağımlılıkların listesini çıkaracak olan -M bayrağına sahiptir. Hangi dosyalarınızın en çok bağımlı olduğu, hangi dosyaların en çok bağımlı olduğu vs. için bu bilgileri kullanabilirsiniz.

Daha fazla bilgi için man page'a bakın. -M'un çeşitli varyantları vardır.

3

birkaç

  • kullanım "önişleyebilir sadece" senin önişlemci çıkışına bakmak için.gcc -E seçeneği, diğer derleyiciler de önceden derlenmiş üstbilgileri kullanırlar (

  • ).

  • gcc da tam ağacı bulunmaktadır görüntülemek -verbose ve --trace seçenekler vardır MSVC Gelişmiş C altında bulunan/showIncludes seçeneği ++ özellik sayfası Ayrıca

, Displaying the #include hierarchy for a C++ file in Visual Studio

1

"Büyük sahiptir Ölçek C++ Yazılım Tasarımı "John Lakos tarafından derleme zamanı bağımlılıklarını kaynak dosyalar arasında ayıklayan araçlara sahipti.

Maalesef Addison-Wesley site kendi depo (AW sitenin kendisi ile birlikte) gitti, ama burada bir tarball bulundu: Ben faydalı birkaç işler önce bulundu http://prdownloads.sourceforge.net/introspector/LSC-rpkg-0.1.tgz?download

ve faziletini vardır Özgür olmak.

BTW, Lakos'un kitabını okumadıysanız, projenizin fayda sağlayacağı anlaşılıyor. (Mevcut sürüm biraz tarihli, ancak Lakos'un 2012'de çıkacak başka bir kitabının olduğunu duydum.)

1

Şahsen, "Bu dosyayı kaldır" diyecek bir araç olup olmadığını bilmiyorum. Gerçekten bir çok şeye bağlı olan karmaşık bir meseledir. İfadeleri içeren bir ağaca baktığımızda kuşkusuz sizi deli edeceksiniz ... Bu beni delirtecek, ayrıca gözlerimi mahvedecek. Derleme sürelerinizi azaltmak için işleri yapmanın daha iyi yolları vardır.

  1. Sınıf yöntemlerinizi tersine uygulayın.
  2. Bunları takip ettikten sonra, içerme ifadelerinizi yeniden inceleyin ve bunları kaldırmaya çalışın. Genellikle onları silmek ve baştan başlamak için yararlıdır.
  3. İleriye doğru beyan kullanmayı tercih etmek mümkün olduğunca çoktur. Başlık dosyalarınızdaki yöntemleri geçersiz kılarsanız, bunu çok yapabilirsiniz.
  4. Büyük başlık dosyalarını daha küçük dosyalara ayırın. Bir dosyadaki bir sınıf çoğu kez daha sık kullanılıyorsa, bunu kendi başına bir başlık dosyasına koyun.
  5. 1000 çeviri birimi aslında çok fazla değil. 10-20 bine sahibiz. :)
  6. Derleme süreleriniz çok uzunsa Incredibuild'i edinin.
0

Bazı araçların olduğunu duydum, ama kullanmıyorum.

Bazı araçlar yarattım https://sourceforge.net/p/headerfinder bu yararlı olabilir. Ne yazık ki

  • Kaynak kod ihtiyacı derlenmiş
  • Çok yavaş ve tüketir belleğe Vb.Net geliştirilen aşağıdaki konularla "HOME MADE" aracıdır.
  • Yardım mevcut değil.
0

GCC Ara dosyalarını kaydedebileceğiniz bir bayrak (-save-temps) vardır. Bu, önişlemcinin sonuçları olan .ii dosyalarını içerir (derlemeden önce). Bunu ayrıştırmak için bir betik yazabilir ve içeriğin ve/veya bağımlılığın ağacının ağırlığını/maliyetini/boyutunu belirtebilirsiniz.

Sadece bunu yapmak için bir Python betiği yazdım (herkese açık: https://gitlab.com/p_b_omta/gcc-include-analyzer).

İlgili konular