2009-02-26 32 views
5

Nếu tôi liên kết tĩnh một tệp thực thi trong ubuntu, có khả năng là tệp thực thi đó sẽ không hoạt động trong một phân phối khác chẳng hạn như os mint? hoặc fedora? Tôi biết các loại vi xử lý bị ảnh hưởng, nhưng khác thì có điều gì khác mà tôi phải cảnh giác không? Xin lỗi nếu đây là một câu hỏi ngu ngốc. Cảm ơn bạn đã giúp đỡSẽ liên kết tĩnh trên một công việc phân phối unix nhưng không liên kết với nhau?

+0

Câu hỏi hay. Một cái gì đó tôi nghĩ về ngày hôm nay. – TheHippo

+1

Bởi "unix", bạn có chắc chắn bạn không có nghĩa là "linux"? – bk1e

Trả lời

3

Nếu bạn liên kết tĩnh một chương trình trên một máy tính và sau đó chuyển nó sang một máy tính khác trong đó hệ thống chạy theo cùng một cách, thì nó sẽ hoạt động tốt. Đó là điểm liên kết tĩnh; rằng không có tệp nào khác mà chương trình phụ thuộc vào - nó hoàn toàn độc lập, miễn là nó có thể chạy ở tất cả, nó sẽ chạy theo cách tương tự trên hệ thống "máy chủ" của nó.

Điều này trái ngược với liên kết động, trong đó chương trình kết hợp các thành phần của các tệp khác (thư viện) khi chạy. Nếu bạn di chuyển một chương trình được liên kết động đến một hệ thống khác, nơi các thư viện mà nó phụ thuộc khác nhau (hoặc không tồn tại), nó sẽ không hoạt động.

+1

Đây là câu trả lời sai, đặc biệt là trên Linux. Nếu câu trả lời này "thắng", thì stackoverflow là vô nghĩa :-( –

+0

-1: Không chỉ có kiến ​​trúc máy tính khi chơi. –

+0

Tôi đã bỏ lỡ, khi tôi viết "kiến trúc" tôi đã nghĩ nhiều hơn chỉ là kiến ​​trúc chip. –

2

Trong hầu hết các trường hợp, tệp thực thi của bạn sẽ hoạt động tốt. Miễn là tệp thực thi của bạn không phụ thuộc vào bất kỳ điều gì bất thường có mặt để nó hoạt động, sẽ không có vấn đề gì. (Và, nếu nó phụ thuộc vào một cái gì đó bất thường đang có mặt, thì bạn sẽ có cùng một vấn đề ngay cả khi bạn liên kết động.)

Liên kết tĩnh thường an toàn hơn liên kết động để tương thích giữa các môi trường UNIX khác nhau, miễn là cùng một CPU đang được sử dụng.

Để có một nhị phân liên kết tĩnh thất bại, một lần nữa giả định kiến ​​trúc bộ vi xử lý tương tự, bạn sẽ phải làm một cái gì đó như liên kết trên một hệ thống sử dụng định dạng nhị phân a.out và thử thực hiện nó trên hệ thống đang chạy ELF, trường hợp phiên bản được liên kết động sẽ không thành công.

Vậy tại sao mọi người không phải là liên kết thường xuyên tĩnh? Có hai lý do:

  • Nó làm cho thực thi lớn hơn, thỉnh thoảng NHIÊU lớn hơn, và
  • Nếu lỗi trong các thư viện được cố định, bạn sẽ phải liên kết lại chương trình của bạn để có được quyền truy cập vào các bản vá lỗi. Nếu một lỗi bảo mật quan trọng được cố định trong các thư viện, bạn phải liên kết lại và phân phối lại exe của bạn.
5

Có một vài trường hợp góc, nhưng đối với hầu hết các phần, bạn phải ở trạng thái tốt với liên kết tĩnh. Một trong đó nói đến cái tâm là libnss. Thư viện cụ thể này về cơ bản là không thể liên kết tĩnh, vì cách nó thực hiện công việc của nó (quyền hạn, xác thực, nhiệm vụ bảo mật). Miễn là các phiên bản glibc là tương tự, bạn nên được ok về vấn đề này, mặc dù.

Nếu chương trình của bạn cần làm việc với các tính năng tinh tế của hạt nhân, như trình quản lý âm lượng, bạn có cơ hội làm chương trình của bạn hoạt động, liên kết tĩnh, trên các bản phân phối, vì giao diện hạt nhân có thể thay đổi đôi chút.

Hầu hết các ứng dụng điển hình, thậm chí có ý nghĩa để thảo luận về tính di động, như dịch vụ mạng, ứng dụng gui, công cụ ngôn ngữ (như trình biên dịch/phiên dịch) sẽ không gặp vấn đề gì.

+0

Mới hơn của glibc sẽ cảnh báo bạn nếu bạn liên kết tĩnh bất kỳ chức năng "vấn đề" nào. Để tìm danh sách đầy đủ, bạn có thể làm "stings -a /usr/lib/libc.a | grep 'trong tĩnh Các ứng dụng liên kết ''. Điều này mang lại cho tôi 73 chức năng trên Fedora 9. KHÔNG bỏ qua cảnh báo này, hoặc bạn sẽ sụp đổ và ghi! –

0

Ngược lại. Dù cơ hội của bạn là nhận được một nhị phân để làm việc trên các bản phân phối hoặc thậm chí OSes, những cơ hội được tối đa hóa bởi liên kết tĩnh. Liên kết tĩnh làm cho một tập tin thực thi độc lập về mặt thư viện. Nó vẫn có thể sai nếu nó cố đọc một tập tin không có trên hệ thống khác.

Để có cơ hội tốt hơn về tính di động, hãy thử liên kết với dietlibc hoặc một số libc khác. An article at Linux Journal đề cập đến một số ứng cử viên. Một libc nhỏ hơn, đơn giản hơn ít có khả năng phụ thuộc vào những thứ trong hệ thống tập tin khác với distro cho distro.

+0

+1 để chỉ ra rằng việc sử dụng libc nhỏ hơn thường là một lựa chọn tốt. rất nhiều cơ sở kể từ glibc là khá lớn, bạn sẽ nhận được rất nhiều nhị phân. –

0

Tôi sẽ, vì những lý do đã nêu ở trên tránh liên kết tĩnh trừ khi bạn hoàn toàn phải.

Điều đó đang được nói, nó sẽ hoạt động trên bất kỳ hạt nhân tương tự khác của cùng một kiến ​​trúc (tức là nếu bạn liên kết tĩnh trên máy chạy Linux 2.4.x, bộ nạp VDSO sẽ khác trên Linux 2.6, VDSO là ảo đối tượng chia sẻ động, một đối tượng được chia sẻ mà hạt nhân trưng ra cho mọi tiến trình có chứa mã trình nạp).

cạm bẫy khác bao gồm mọi thứ trong/etc không phải là nơi bạn sẽ nghĩ, nhật ký là ở những nơi khác nhau, tiện ích hệ thống đang vắng mặt hoặc khác nhau (ubuntu sử dụng update-rc.d, RHEL sử dụng chkconfig) vv

Đôi khi bạn không có lựa chọn nào khác. Tôi đã viết một chương trình nói chuyện với giao diện cmdlib dựa trên chuỗi LVM2 có lợi cho việc sử dụng execv() .. thấp và nhìn, 30% các bản phân phối mà tôi cần để hỗ trợ KHÔNG bao gồm thư viện đó và không có cách nào để nhận nó. Vì vậy, tôi phải liên kết với đối tượng tĩnh khi tạo các gói nhị phân.

Nếu bạn đang sử dụng glibc, bạn có thể tự tin rằng những thứ như getpwnam() và bạn bè sẽ vẫn làm việc .. chỉ cần đảm bảo để xem bất kỳ đường dẫn cứng mã hoá (tốt hơn nữa, làm cho họ có thể cấu hình tại thời gian chạy)

0

Miễn là bạn có thể đảm bảo nó sẽ chỉ được thực hiện trên một phiên bản tương tự của hệ điều hành trên phần cứng tương tự, chương trình của bạn sẽ hoạt động tốt nếu nó được liên kết tĩnh. vì vậy, nếu bạn xây dựng cho một Linux 2.6 và liên kết tĩnh, bạn sẽ ổn khi chạy trên (gần như) tất cả 2.6 bản phân phối Linux.

Được cảnh báo bạn không thể liên kết tĩnh một số phần của GLIBC vì vậy nếu bạn đang sử dụng chúng, bạn sẽ phải liên kết động anyway. Từ bộ nhớ tên công cụ dịch vụ (nss) phần yêu cầu liên kết động khi tôi đang điều tra nó.

Bạn không thể liên kết tĩnh một chương trình cho (nói) Linux sau đó mong đợi nó chạy trên BSD hoặc Windows. BSD và Unix không trình bày hoặc xử lý các cuộc gọi hệ thống của họ theo cách giống như Linux. Tôi nói một lời nói dối nhỏ bởi vì các BSD có một lớp mô phỏng Linux có thể được kích hoạt, nhưng ra khỏi hộp nó sẽ không hoạt động.

0

Không, nó sẽ không hoạt động. Liên kết tĩnh cho độc lập phân phối là một khái niệm từ các độ tuổi cũ và không được khuyến nghị. Bởi thực tế bạn không thể như nhiều thư viện không phải là avail như thư viện tĩnh anyway.

Theo cách cơ sở tiêu chuẩn Linux, đây là cơ hội duy nhất của bạn để nhận được nhiều khả năng phân phối chéo nhất có thể.

LSB cũng hoạt động tốt nếu bạn lập trình cho FreeBSD và Solaris.

0

Có hai câu hỏi tương thích được đề cập ở đây: các phiên bản thư viện và khoảng không quảng cáo thư viện.

Bạn không nói bạn đang sử dụng thư viện nào.

Nếu bạn không có tùy chọn '-l', thì 'thư viện' duy nhất là glibc, chính nó là giao diện cho hạt nhân. Các phiên bản glibc tương thích với nhau. Nếu bạn liên kết trên một hệ thống glibc 2.x bạn có thể chạy trên glibc 2.y, với y> x. Các nhà phát triển thực hiện một cam kết chắc chắn về điều này.

Nếu bạn có tùy chọn -l, liên kết tĩnh luôn an toàn. Nếu bạn được liên kết động, bạn phải đảm bảo rằng (1) thư viện có mặt trên hệ thống đích, và (2) có một phiên bản tương thích. Mileage của bạn có thể Khác nhau về việc liệu distro mục tiêu có những gì bạn cần.

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