2011-07-13 66 views
25

Một đồng nghiệp gần đây đã tiết lộ với tôi rằng một tệp nguồn duy nhất của chúng tôi bao gồm hơn 3.400 tiêu đề trong thời gian biên dịch. Chúng tôi có hơn 1.000 đơn vị dịch thuật được biên soạn trong một bản dựng, dẫn đến một hình phạt hiệu suất rất lớn đối với các tiêu đề chắc chắn không phải tất cả đều được sử dụng.Tiêu đề bao gồm các công cụ phân tích tĩnh?

Có công cụ phân tích tĩnh nào có thể làm sáng tỏ các cây trong khu rừng như vậy, cụ thể là cho chúng ta khả năng quyết định cái nào chúng ta nên làm việc để tách ra?

CẬP NHẬT

Tìm thấy một số thông tin thú vị về các chi phí bao gồm một tập tin header (và các loại bao gồm bảo vệ để tối ưu hóa đưa nó) here, có nguồn gốc từ this question.

+0

Nền tảng nào? gcc có các tùy chọn có thể giúp điều này (nếu không ai đề xuất ý tưởng tốt hơn) – Nemo

+0

@Nemo: Cả gcc và MSVC. – fbrereto

+0

Bản sao có thể có của http://stackoverflow.com/questions/42308/tool-to-track-include-dependencies – jfritz42

Trả lời

23

Đầu ra của gcc -w -H <file> có thể hữu ích (Nếu bạn phân tích cú pháp và đặt một số số đếm), -w có thể chặn tất cả cảnh báo, điều này có thể khó xử lý.

Từ các tài liệu gcc:

-H

In tên của mỗi tập tin tiêu đề sử dụng, ngoài các hoạt động bình thường khác. Mỗi tên được thụt vào để hiển thị mức độ sâu trong ngăn xếp #include. Các tệp tiêu đề biên dịch sẵn cũng được in, ngay cả khi chúng được tìm thấy là không hợp lệ; tiêu đề được biên dịch trước không hợp lệ tệp được in với ...x và tệp hợp lệ có ...!.

Kết quả trông như thế này:

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

không tồn tại một cái gì đó tương tự cho devenv/msvs? – andreas

+0

@ user375251 Tôi không biết, không sử dụng chuỗi công cụ MS cho bất cứ điều gì, hãy kiểm tra MSDN – Spudd86

+0

@ Spudd86 tôi có thể nhận danh sách bao gồm cho mọi tệp trong dự án mà không phải nhập từng tên tệp bằng tùy chọn -H theo cách thủ công không? – Alecs

3

Nếu bạn đang sử dụng gcc/g ++, -M or -MM option sẽ xuất một dòng với thông tin bạn tìm kiếm. (Các cựu sẽ bao gồm tiêu đề hệ thống trong khi sau này sẽ không có biến thể khác;. Xem hướng dẫn.)

$ 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 

Bạn sẽ cần phải loại bỏ các foo.o: foo.c ngay từ đầu, nhưng phần còn lại là một danh sách của tất cả các tiêu đề rằng tệp phụ thuộc vào, vì vậy sẽ không quá khó để viết một tập lệnh để thu thập chúng và tóm tắt chúng.

Tất nhiên, đề xuất này chỉ hữu ích trên Unix và chỉ khi không ai khác có ý tưởng tốt hơn. :-)

+1

không quá hữu ích để tìm ra nơi tất cả các bao gồm đến từ – Spudd86

1

GCC có cờ -M sẽ xuất danh sách phụ thuộc cho tệp nguồn đã cho. Bạn có thể sử dụng thông tin đó để tìm ra tệp nào của bạn có nhiều phụ thuộc nhất, tệp nào phụ thuộc nhiều nhất, v.v.

Kiểm tra man page để biết thêm thông tin. Có một số biến thể của -M.

3

một vài things-

  • sử dụng "preprocess chỉ" nhìn vào sản lượng tiền xử lý của bạn.tùy chọn gcc -E, các trình biên dịch khác có chức năng quá

  • sử dụng các tiêu đề được biên dịch trước.

  • gcc có các tùy chọn -verbose và --trace mà cũng hiển thị đầy đủ bao gồm cây, MSVC có quyền lựa chọn/showIncludes tìm thấy trong phần Advanced C++ sở hữu trang

Ngoài ra, Displaying the #include hierarchy for a C++ file in Visual Studio

1

"lớn Quy mô C++ Thiết kế phần mềm "của John Lakos có các công cụ trích xuất các phụ thuộc biên dịch trong các tệp nguồn.

Thật không may, kho của họ trên trang web của Addison-Wesley là ra đi (cùng với trang web của AW của chính nó), nhưng tôi tìm thấy một tarball đây: http://prdownloads.sourceforge.net/introspector/LSC-rpkg-0.1.tgz?download

tôi thấy nó hữu ích một số công việc trước, và nó có đức hạnh của được tự do.

BTW, nếu bạn chưa đọc sách của Lakos, có vẻ như dự án của bạn sẽ được hưởng lợi. (Phiên bản hiện tại có một chút ngày, nhưng tôi nghe nói rằng Lakos có một cuốn sách khác sắp ra mắt vào năm 2012.)

1

Cá nhân tôi không biết nếu có công cụ sẽ nói "Xóa tệp này". Nó thực sự là một vấn đề phức tạp phụ thuộc vào rất nhiều thứ. Nhìn vào một cây bao gồm các tuyên bố chắc chắn sẽ lái xe bạn hạt .... Nó sẽ khiến tôi điên, cũng như làm hỏng đôi mắt của tôi. Có nhiều cách tốt hơn để làm mọi thứ để giảm thời gian biên dịch của bạn.

  1. Bỏ nội tuyến phương pháp lớp học của bạn.
  2. Sau khi rút gọn, hãy kiểm tra lại các câu lệnh bao gồm của bạn và cố gắng xóa chúng. Thường hữu ích khi xóa chúng và bắt đầu lại.
  3. Ưu tiên sử dụng các khai báo chuyển tiếp càng nhiều càng tốt. Nếu bạn de-inline phương pháp trong các tập tin tiêu đề của bạn, bạn có thể làm điều này rất nhiều.
  4. Chia nhỏ các tệp tiêu đề lớn thành các tệp nhỏ hơn. Nếu một lớp trong một tập tin được sử dụng thường xuyên hơn hầu hết, sau đó đặt nó trong một tập tin tiêu đề tất cả bởi chính nó.
  5. 1000 đơn vị dịch thuật không thực sự nhiều lắm. Chúng ta có từ 10-20 nghìn. :)
  6. Nhận Incredibuild nếu thời gian biên dịch của bạn vẫn còn quá dài.
0

Tôi nghe nói có một số công cụ làm điều đó, nhưng tôi không sử dụng chúng.

Tôi đã tạo một số công cụ https://sourceforge.net/p/headerfinder có thể hữu ích. Đáng tiếc là nó là "HOME MADE" công cụ với các vấn đề sau đây,

  • Được phát triển trong Vb.Net
  • Source code cần phải biên soạn
  • nhớ Rất chậm và tiêu thụ.
  • Không có trợ giúp.
0

GCC Có cờ (tiết kiệm nhiệt độ) mà bạn có thể lưu tệp trung gian. Điều này bao gồm các tệp .ii, là kết quả của bộ tiền xử lý (trước khi biên dịch). Bạn có thể viết một kịch bản để phân tích cú pháp này và xác định trọng lượng/chi phí/kích thước của những gì được bao gồm, cũng như cây phụ thuộc.

Tôi đã viết một tập lệnh Python để thực hiện điều này (có sẵn công khai tại đây: https://gitlab.com/p_b_omta/gcc-include-analyzer).

Các vấn đề liên quan