5

Tôi đang cố gắng biên dịch một nhị phân của một dự án mã nguồn mở để người dùng của chúng ta không phải tự biên dịch nó.Tạo một nhị phân chung trong linux cho tất cả các máy x86

Tôi nhận thấy rằng một số tệp nhị phân được tạo trên một máy ubuntu 32 bit "A" không hoạt động trên máy 32 bit "B", có lỗi liên quan đến việc thiếu tệp .so đang được báo cáo.

Tuy nhiên, nếu tôi biên dịch từ đầu trên máy "B", thì tất cả các lỗi đều biến mất.

Có thể có bất kỳ lý do gì để biên dịch mã trên máy đích làm cho các lỗi này biến mất không? Tôi chỉ chạy "./configure" và "make" - không phải "make-install", Vì vậy, nó không giống như tôi đã tạo ra những tệp này .so có sẵn trên toàn cầu.

Có thể trình biên dịch phát hiện có các tệp .so bị thiếu trong thư viện hệ thống và trong trường hợp này liên kết một thư viện tĩnh vào tệp thực thi?

Ubuntu biên dịch các gói của nó sao cho gói i386 chạy trên tất cả các máy x86?

Trả lời

6

Tôi đoán vấn đề được gọi là "khả năng tương thích nhị phân" (có a tag về tràn ngăn xếp dành cho những sự cố này). Khi bạn liên kết một nhị phân trên một máy, môi trường xung quanh ảnh hưởng đến hệ nhị phân, và, đã được chạy trên một máy khác, nó vẫn cố gắng tìm môi trường tương tự như môi trường đã biên dịch.

Dung sai cho các môi trường khác nhau trong trường hợp này được gọi là khả năng tương thích nhị phân.

Cách hoạt động?

Điểm mấu chốt ở đây là, ngay cả khi bạn chỉ định các tùy chọn tương tự để mối liên kết trên các máy khác nhau, bạn vẫn có thể nhận được nhị phân khác nhau. Ví dụ: nếu bạn liên kết nhị phân của mình với thư viện được chia sẻ với -lfoo, phiên bản chính xác của foo bạn có trên máy mà bạn xây dựng (ví dụ: libfoo.so.5) được mã hóa thành nhị phân. Khi nó chạy trên máy B, nó chỉ có thể chứa libfoo.so.4 và nhị phân sẽ từ chối chạy vì nó cần thiếu libfoo.so.5 để tệp. Đó là lý do tại sao biên dịch lại giúp, và không có nó, nó không hoạt động.

Gói Ubuntu — và bất kỳ gói phân phối nào khác — là tất cả được biên dịch trong cùng một môi trường (với nhau). Đó là lý do tại sao họ cài đặt tốt. Và các nhà cung cấp phân phối xem mỗi phiên bản tiếp theo tương thích ngược với các phiên bản trước đó.

Tôi nên làm gì?

Nếu bạn muốn làm cho phần mềm của bạn tương thích với các bản phân phối khác nhau, nó dễ dàng hơn bạn nghĩ. Trước tiên, hãy thử biên dịch đơn đăng ký của bạn theo phân phối cũ nhất có thể. Vì, như tôi đã đề cập trước đây, các bản phân phối hiện đại thường tương thích ngược, ý chí mềm mại của bạn, rất có thể, chạy trên các bản phân phối mới hơn mà không có vấn đề gì.

Để kiểm tra gói kết quả kỹ lưỡng hơn và nhận thêm lời khuyên về khả năng tương thích, bạn có thể sử dụng công cụ miễn phí Linux Application Checker của chúng tôi. Bạn cũng có thể quan tâm generic tips for packaging Linux soft.

+2

Đúng vậy, nhưng đừng đi quá xa. Biên dịch nhị phân trên RHEL 4 sẽ không có khả năng hoạt động trên bất kỳ bản phân phối hiện đại nào. Ít nhất libc là yếu tố quyết định chính, nó thường bị khóa vào một phiên bản nhỏ cụ thể. – Keith

+0

PS. Đây cũng là lý do tại sao một số ứng dụng thương mại xuất xưởng với toàn bộ các thư viện chỉ cho chính nó và sử dụng LD_LIBRARY_PATH để đảm bảo chúng được sử dụng thay vì các ứng dụng hệ thống. Một tùy chọn khác là liên kết tĩnh. Đối với các công cụ nhỏ hoạt động tốt. – Keith

2

Bạn có thể sử dụng một dự án như Ermine để tạo phân phối các tệp nhị phân gốc được liên kết động với các thư viện được chia sẻ đi kèm.

Bên ngoài đó, bạn có thể biên dịch mã của bạn tĩnh. Điều này sẽ yêu cầu bạn lấy mã nguồn cho toàn bộ cây phụ thuộc của bạn, biên dịch chúng và tham khảo các tệp nhị phân được biên dịch khi bạn tạo mã của mình. Bạn không thể biên dịch các tệp nhị phân tĩnh đối với các thư viện được chia sẻ khác (các tệp .so). Điều này có thể là một nỗi đau thực sự, đặc biệt là nếu phụ thuộc của bạn có phụ thuộc của riêng họ.

+0

Ermine có vẻ tốt. Nhưng nó không phải là miễn phí. Bạn có biết về bất kỳ lựa chọn thay thế miễn phí nào không? – shivams

3

Nếu bạn biên dịch mã trên máy, rất có thể bạn sẽ không gặp bất kỳ lỗi nào liên quan đến thiếu libs nếu bạn thực thi chương trình trên máy này. Trong quá trình cấu hình chạy tất cả các thư viện cần thiết được phát hiện (đây là lý do chính cấu hình, autotools vv tồn tại) và các cờ thích hợp, như -lsomelib và -I/some/include/patch được ghi vào makefile và chuyển tới trình biên dịch và trình liên kết .

Tôi sao chép tệp thực thi đó sang một máy khác mà máy có thể có libs ở phiên bản sai hoặc thiếu, vì vậy nó có thể không chạy.

Kịch bản cấu hình thường sẽ không xây dựng các tệp nhị phân tĩnh, trừ khi bạn đã yêu cầu nó làm như vậy một cách rõ ràng.

Gói Ubuntu sẽ không chạy trên tất cả các máy x86. Nhưng trình quản lý gói thực hiện độ phân giải phụ thuộc để đảm bảo không có thư viện hoặc thư viện sai nào bị thiếu và từ chối cài đặt gói khác. Nếu bạn buộc cài đặt bất kể thiếu phụ thuộc, bạn có thể chạy trong cùng một vấn đề với thiếu libs một lần nữa.

Nếu bạn muốn đảm bảo rằng gói của bạn có thể trên bất kỳ máy nào, chỉ cần liên kết nó tĩnh.

Nếu đủ để chạy nó trên một bản phân phối cụ thể (ví dụ: Ubuntu), bạn có thể tự mình tạo một gói. Điều này đòi hỏi một số nỗ lực nhiều hơn nữa.

0

Thay vì lỗi dễ bị tiếp cận LD_LIBRARY_PATH (cũng yêu cầu tương tác người dùng) hoặc liên kết tĩnh (không phải lúc nào cũng có thể hoặc bị cấm bởi GPL), bạn có thể thử sử dụng đường dẫn tương đối làm đường dẫn tìm kiếm thư viện (được cung cấp trong cửa sổ theo chuẩn lần). Sử dụng cờ $ORIGIN với trình liên kết.

Cách tiếp cận hoàn chỉnh được mô tả độc đáo trong số blog (archived version) này.