2009-02-09 37 views
7

Chúng tôi hiện đang sử dụng một công cụ dòng lệnh đơn lẻ để xây dựng sản phẩm của chúng tôi trên cả Windows và Linux.Làm cách nào để hợp nhất nhiều tệp PDB?

Si xa các tác phẩm của nó một cách độc đáo, cho phép chúng tôi xây dựng nguồn và phụ thuộc tốt hơn so với bất kỳ hệ thống xây dựng nào trước đây của chúng tôi cho phép. Điều này giúp chúng tôi tăng khả năng xây dựng gia tăng và song song.

Để mô tả một thời gian ngắn quá trình xây dựng, chúng tôi nhận được thông thường:

.cpp -- cl.exe --> .obj and .pdb 
multiple .obj and .pdb -- cl.exe --> single .dll .lib .pdb 
multiple .obj and .pdb -- cl.exe --> single .exe .pdb 

MSVC C/C++ biên dịch hỗ trợ nó đầy đủ.

Gần đây, cần phải xây dựng một vài thư viện tĩnh xuất hiện. Từ những gì chúng tôi thu thập được, quá trình xây dựng một thư viện tĩnh là:

multiple .cpp -- cl.exe --> multiple .obj and a single .pdb 
multiple .obj -- lib.exe --> a single .lib 

Các PDB đơn có nghĩa là cl.exe chỉ nên được thực hiện một lần cho tất cả các nguồn cpp. Việc thực thi đơn này có nghĩa là chúng ta không thể song song việc xây dựng cho thư viện tĩnh này. Điều này thực sự không may.

Chúng tôi điều tra một chút nữa và theo các tài liệu (và các tùy chọn dòng lệnh có sẵn):

  • cl.exe không biết làm thế nào để xây dựng thư viện tĩnh
  • lib.exe không biết làm thế nào để xây dựng PDB tệp

Có ai biết cách hợp nhất nhiều tệp PDB không? Chúng ta có phải chịu số lần xây dựng chậm cho các thư viện tĩnh không? Các công cụ như Incredibuild hoạt động như thế nào xung quanh vấn đề này?

+0

Bạn luôn có thể đặt mã của mình trên ổ đĩa trạng thái rắn. Các bản dựng sẽ nhanh như chớp. –

+0

Tôi đang ở trên một ổ đĩa trạng thái rắn trên phong cách của tôi. Nó giúp, nhưng liên kết là IO bị ràng buộc, biên dịch là CPU bị ràng buộc. –

Trả lời

5

Tôi đã không thực hiện C++ trong một thời gian dài nhưng từ đây article, có vẻ như đây là một mẹo hiệu suất để ngừng giải trí các ký hiệu cho các tiêu đề chung.

Bạn có thể thử/Z7 để nhúng thông tin trong mỗi obj, và không tạo ra một PDB và sau đó liên kết và tạo lại nó với một rebase như trong article này.

+0

Không phải là thông tin gỡ lỗi từ/Z7 khác nhau (và kém hơn) từ những gì được tạo ra bởi/Zi và/ZI? Theo bài viết liên quan đến trong quán cà phê egghead thead (http://support.microsoft.com/kb/258205), bạn có thể trích xuất thông tin gỡ lỗi từ/Z7 thành tệp .dbg chứ không phải tệp .pdb. –

+1

cả hai liên kết này đều đã chết: ( –

5

Không cần phải hợp nhất các tệp PDB.

Biên dịch tệp nguồn bằng/Z7 để tránh tạo PDB trong các bước CL.EXE.

Sử dụng LIB.EXE để tạo các libar tĩnh với thông tin gỡ lỗi được nhúng. Sử dụng LINK.EXE thay vì CL.EXE để liên kết, sử dụng/PDB để chỉ định nơi thông tin gỡ lỗi đi.

Nếu bạn đang gỡ lỗi một quá trình với EXE và một hoặc nhiều DLL, hãy nạp trình gỡ lỗi PDB cho mỗi hình ảnh (EXE hoặc DLL).

2

Kết hợp các tệp PDB là có thể nhưng chỉ có thể được thực hiện bởi cl.exe và link.exe. Tôi KHÔNG biết bất kỳ công cụ độc lập nào để hợp nhất các tệp PDB.

Bạn có thể sử dụng tùy chọn/PDB để liên kết (Tôi đã kiểm tra VC2005) để chỉ định tên tệp pdb thay thế.

Microsoft cũng đề xuất bao gồm tệp PDB (mỗi obj có tệp PDB tương ứng) cùng với tệp .LIB.

Bạn không thể lưu trữ tệp PDB bên trong tệp .LIB, tôi đã thử với VC2003, không thành công.

Biên dịch với/Z7 có thể tránh tệp PDB cho .LIB, nhưng tệp đối tượng lớn, trừ khi tệp link.exe loại bỏ thông tin gỡ lỗi. Nếu bạn không có/debug tùy chọn để liên kết, sau đó exe của bạn/dll không thể được gỡ lỗi.

Trình biên dịch (cl.exe) luôn ghi vào tệp vcXX.pdb trừ khi bạn sử dụng tùy chọn/Fd để chỉ định một tên khác. Ngay cả khi bạn sử dụng cl.exe để tạo ra tệp thực thi "trực tiếp", nó sẽ tạo tệp vc80.pdb và sau đó link.exe sẽ tạo tên tệp pdb giống như tệp thực thi.

cl/Zi test.c

cl.exe -> vc80.pdb link.exe đọc vc80.pdb (tên được nhúng trong tập tin test.obj) -> test.pdb

Mỗi khi cl/Zi/c biên dịch một tệp, nó sẽ cố gắng sửa đổi tệp vcXX.pdb hiện có thay vì ghi đè lên nó.

Tôi nhận được sự liên kết trên bằng cách chơi với trình biên dịch một lần nữa và một lần nữa, sau đó nắm bắt kết quả procexp của sysinternals và phân tích nó. Hy vọng nó giúp.

0

Trừ khi bạn muốn phân phối lại thư viện tĩnh có thông tin gỡ lỗi, bạn không thực sự cần hợp nhất bất kỳ tệp PDB nào (hoặc sử dụng /Z7 để nhúng thông tin gỡ lỗi).

Như @zhaorufei đã đề cập, khi sử dụng /Zi, mỗi tệp đối tượng chứa tham chiếu đến tệp PDB của nó, mà trình liên kết sẽ sử dụng.

Đơn giản chỉ cần sử dụng /Fd để cung cấp cho mỗi đối tượng một tập tin PDB độc đáo:

> cl -c foo.cpp -Fo:target/foo.obj -Fd:target/foo.pdb -Zi 
> cl -c bar.cpp -Fo:target/bar.obj -Fd:target/bar.pdb -Zi 

> strings target/foo.obj | grep pdb 
D:\Dev\sample\target\foo.pdb 
> strings target/bar.obj | grep pdb 
D:\Dev\sample\target\bar.pdb 

này cũng có những lợi ích mà nó hoạt động xung quanh các vấn đề về truy cập đồng thời vào các tập tin PDB chia sẻ đề cập here, vì vậy bạn có thể parallelize các biên dịch bước như bạn muốn.

Sau đó liên kết/lưu trữ các tệp đối tượng như bình thường. VC++ đã nhúng các loại thông tin khác nhau trong các tệp đối tượng để chuyển chúng tới trình liên kết, chẳng hạn như thiết lập liên kết thời gian chạy và thư viện phụ thuộc - đường dẫn tệp PDB không khác nhau. Tạo một thư viện tĩnh từ các đối tượng không loại bỏ các tài liệu tham khảo:

> lib -out:target/all.lib target/foo.obj target/bar.obj 
> strings target/all.lib | grep pdb 
D:\Dev\sample\target\bar.pdb 
D:\Dev\sample\target\foo.pdb 

Khi liên kết thư viện này đến một thực thi hoặc DLL, các mối liên kết vẫn còn kéo theo cả thông tin gỡ lỗi từ PDBs tham chiếu và thêm nó vào tập tin PDB thức .

Thông báo trước tôi có thể thấy là đường dẫn luôn tuyệt đối, vì vậy điều này có thể không hoạt động nếu bạn di chuyển các tệp xung quanh cục bộ hoặc tới máy khác trước khi liên kết.

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