Là thư viện tĩnh C nhăn mặt? [đóng cửa]


11

Có 2 đối số để có thư viện chia sẻ:

  1. Nó giúp giảm không gian đĩa.
  2. Khi một thư viện chia sẻ được cập nhật, tất cả các nhị phân tùy thuộc vào nó sẽ nhận được bản cập nhật.

Chủ yếu có một nhược điểm đối với các thư viện dùng chung:

  • Họ (có thể) giới thiệu địa ngục phụ thuộc.

Trên máy tính để bàn, lợi thế thứ 1 không thực sự giữ được nữa. Lãng phí không gian đĩa ngày nay không phải là vấn đề.

Có các nhị phân tĩnh sẽ cho phép chúng ta có được các trình quản lý gói tốt hơn - ý tôi là, địa ngục phụ thuộc sẽ là quá khứ. Thêm một chương trình sẽ chỉ là thêm một nhị phân; cuối cùng là một thư mục để cho phép nó xử lý các tập tin của nó. Xóa một chương trình sẽ chỉ đơn giản là xóa tập tin này. Phụ thuộc? Không còn.

Lợi thế thứ 2 vẫn còn, nhưng tôi nghĩ lợi thế của nhị phân tĩnh trên máy tính để bàn vượt trội hơn nó. Ý tôi là, ngay cả những ngôn ngữ mới như Go cũng biên dịch tất cả các nhị phân của chúng bất chấp những lợi thế của thư viện dùng chung, vì sự tiện lợi.


Vì một trong những lợi thế chính của các thư viện chia sẻ không còn là vấn đề lớn nữa, nên các thư viện tĩnh C có còn được tán thành không? Nếu vậy, tại sao?


4
Lý do chính khiến C được sử dụng nữa là do bạn không làm việc trên các máy tính để bàn hiện đại.
Telastyn

18
@Telastyn Tôi xin lỗi? Hầu hết các phần mềm được cài đặt trên máy tính để bàn của tôi được viết bằng C.
Florian Margaine

6
Side bit - một trang web tắt đọc về chủ đề - Liên kết động được coi là có hại

6
Một lợi ích của các thư viện động là mọi người vẫn có thể cập nhật các thư viện để khắc phục các lỗi, lỗ hổng bảo mật hoặc các sự cố phần cứng trong trò chơi nguồn đóng 15 năm của bạn từ lâu đã ngừng nhận cập nhật. Một loại trường hợp thích hợp nhưng vì các trò chơi hay không phải là hàng hóa, "chỉ cần sử dụng một chương trình khác" không thực sự có ích. Nó cũng quan trọng cho việc tuân thủ LGPL mà không cần tìm nguồn mở mã của riêng bạn.
Doval

4
Bạn đã quên hai ưu điểm khác của các thư viện dùng chung: 1) chúng cũng được chia sẻ trong bộ nhớ, 2) tất cả các trình liên kết đều bị ảnh hưởng xấu và việc liên kết một nhị phân lớn rất khó chịu. Việc chia một nhị phân thành nhiều thực thể nhỏ hơn làm cho toàn bộ quá trình trở nên dễ chịu hơn nhiều.
SK-logic

Câu trả lời:


9

Tiền đề của câu hỏi của bạn là thiếu sót. Điều gì được tán thành là dính vào các học thuyết và tuyệt đối mà không hiểu gì về cơ sở đằng sau chúng (Lập trình Cult Cult?).

Câu trả lời SO được liên kết là một nghiên cứu thú vị trong chính chủ đề đó - Câu hỏi là về lý do tại sao một biên dịch với tùy chọn -static không hoạt động, câu trả lời bạn liên kết không gì khác hơn là không sử dụng liên kết tĩnh. Nếu không thảo luận về lý do tại sao nó xấu và yêu cầu OP sử dụng liên kết động. Thật không may, nó được đánh dấu là câu trả lời đúng (câu trả lời sau có số phiếu nhiều gấp đôi và là câu trả lời đúng cho câu hỏi của OP) bởi vì mặc dù câu trả lời đúng là có, nhưng nó ẩn sâu trong một ý kiến ​​giáo điều.

Câu hỏi thực sự là những ưu và nhược điểm của liên kết tĩnh so với liên kết động và khi nào thì cái này sẽ được ưu tiên hơn cái kia.


2
Câu trả lời Basile của không cho bạn biết chính xác lý do tại sao ông khuyến cáo sử dụng các thư viện chia sẻ: ? "Tại sao bạn muốn liên kết tĩnh ứng dụng của bạn . Nó thường là một sai lầm (vì bạn không lợi nhuận từ bản cập nhật cho các thư viện hệ thống động) Đặc biệt chuyển đổi dịch vụ tên các cơ sở từ libc muốn các thư viện động. " Nó không phải là" mánh khóe "chỉ vì bạn không đồng ý với nó.
Cody Grey

@Cody Câu trả lời được liên kết đến đã được chỉnh sửa kể từ khi tôi gọi nó là một câu nói. Ý kiến ​​duy nhất tôi giữ liên kết tĩnh và liên kết động là sử dụng một liên kết phù hợp với nhu cầu của bạn, và hiểu những điểm mạnh và điểm yếu của sự lựa chọn thay vì rơi vào học thuyết lập trình sùng bái vì "ai đó đã nói như vậy".
mattnz

Vâng, phần "Đặc biệt ..." đã được thêm vào. Không chắc làm thế nào mà ảnh hưởng đến tình trạng rant của nó. Tất nhiên tôi không ủng hộ lập trình sùng bái hàng hóa. Chỉ là những người đề xuất liên kết tĩnh (theo kinh nghiệm của tôi) thường bỏ lỡ hoặc đánh giá thấp các mối quan tâm bảo mật. Liên kết tĩnh có thể rất thích hợp cho các tiện ích một lần, làm cho ứng dụng độc lập và do đó phân phối dễ dàng hơn nhiều. Nhưng bất kỳ ứng dụng nào sẽ được triển khai rộng rãi hoặc được sử dụng để sản xuất nên thực sự liên kết đến một thư viện chia sẻ. Không có nhược điểm thực sự: ở cấp ứng dụng này, bạn đã cần một quy trình triển khai.
Cody Grey

1
Ví dụ điển hình về nơi liên kết tĩnh thích hợp là nơi tôi làm việc - các hệ thống quan trọng trong cuộc sống lớn, phức tạp. Khi một mô-đun quan trọng được kiểm tra và phê duyệt để vận hành, hành vi của nó không được thay đổi mà không trải qua 'quá trình'. Tuy nhiên, không có phần quan trọng nào trong hoạt động và phi nhân thọ của hệ thống (thanh toán và báo cáo) cần kiểm soát kém mạnh mẽ hơn và sử dụng liên kết động.
mattnz

7

Từ quan điểm của nhà phát triển, liên kết động thường có thể tăng tốc đáng kể vòng lặp biên dịch / liên kết / kiểm tra của bạn.

Từ quan điểm quản lý gói, lấy libGL chẳng hạn. Tôi có khoảng một tá các triển khai khác nhau có sẵn trong trình quản lý gói của mình, một số thẻ đồ họa cụ thể và chung chung nhắm mục tiêu. Nếu nó không được liên kết động, sẽ phải có hàng tá phiên bản của mỗi chương trình liên kết với libGL, nếu không bạn sẽ phải tạo ra một lớp trừu tượng bổ sung không hiệu quả như một lệnh gọi hàm.

Hãy nghĩ về một vấn đề bảo mật trong một thư viện phổ biến như Qt. Với liên kết động, tôi chỉ có thể cập nhật một gói đó, thay vì phải xác định, biên dịch lại và triển khai mọi gói duy nhất liên kết trong Qt.

Liên kết tĩnh có thể có lợi thế trong các ứng dụng nguồn đóng được triển khai độc lập, nhưng trong quản lý gói nguồn mở, điều đó gây tổn hại nhiều hơn là giúp ích.


2
Điều này là đúng (tăng tốc độ phát triển), nhưng thật sự bực bội khi nó đưa nó vào sản xuất. Ví dụ kinh điển là Firefox. Lượng nỗ lực kỹ thuật (dưới dạng các bản hack ghê tởm) đã tăng tốc độ phân giải biểu tượng liên kết động để Firefox tải trong thời gian hợp lý là hoàn toàn điên rồ. Hiệu suất tốt hơn nhiều có thể đạt được với chi phí kỹ thuật ít hơn nhiều nếu họ chỉ sẵn sàng liên kết tĩnh tất cả các mã trong dự án của họ (trong khi vẫn còn các thư viện và plugin hệ thống liên kết động, nếu muốn).
R .. GitHub DỪNG GIÚP ICE

5

Các thư viện dùng chung được các nhà bảo trì phân phối Linux ưa thích vì lý do cơ bản # 2 của bạn. Ví dụ, điều thực sự quan trọng đối với họ là, khi ai đó tìm thấy lỗi bảo mật trong zlib , họ không phải biên dịch lại từng chương trình sử dụng zlib --- không chỉ họ sẽ tốn nhiều chu kỳ CPU hơn để thực hiện biên dịch lại, mọi người sử dụng bản phân phối sau đó sẽ phải tải xuống lại tất cả các chương trình đó. Trong khi đó, trong tập hợp các gói được cung cấp bởi một bản phân phối, địa ngục phụ thuộc không phải là một vấn đề, bởi vì mọi thứ đều được kiểm tra để hoạt động với bộ thư viện đó.

Nếu bạn đang xây dựng phần mềm của bên thứ ba cần các thư viện không có trong bản phân phối của bạn, thì việc liên kết tĩnh các thư viện đó có thể ít rắc rối hơn so với giải pháp thay thế và điều đó tốt.

Một điều quan trọng khác cần biết là cả GNU libcvà GCC libstdc++đều có các thành phần không hoạt động đáng tin cậy nếu thư viện được liên kết tĩnh. Vấn đề phổ biến nhất là với dlopen, bởi vì bất kỳ mô-đun nào bạn tải dlopenđều tự liên kết với nó libc.so.6. Vì vậy, điều đó có nghĩa là bây giờ bạn có hai bản sao của thư viện C trong không gian địa chỉ của bạn và sự vui nhộn xảy ra khi họ không đồng ý về bản sao nào của malloccấu trúc dữ liệu nội bộ (ví dụ) có thẩm quyền. Nó trở nên tồi tệ hơn: cả đống chức năng dường như không có gì để làm dlopen, thích gethostbynameiconvsử dụngdlopenbên trong (để hành vi của họ có thể cấu hình thời gian chạy). May mắn thay, ABI cho libc và libstdc ++ rất ổn định, do đó bạn không gặp phải vấn đề nào khi tự động liên kết chúng.


2

Tôi đồng ý với điểm cuối cùng của mattnz: câu hỏi này là một câu hỏi được tải. Nó giả định rằng liên kết tĩnh là xấu. Tôi có thể nghĩ về hai lý do tại sao đây không phải là trường hợp:

  • Liên kết tĩnh là an toàn: nếu thư viện dùng chung được cập nhật sao cho ứng dụng sử dụng cái mới (có thể cái mới ghi đè lên cái cũ hoặc cái cũ bị xóa), nó có thể gây nguy cơ rằng phiên bản mới phá vỡ ứng dụng. Đây là một thay đổi mã ngoài phạm vi của một bản cập nhật chính thức cho ứng dụng. Nó có thể chưa được thử nghiệm. Liên kết tĩnh vượt qua điều này bằng cách không chia sẻ thư viện bên ngoài. Tôi cho rằng đây là một bất lợi cho các thư viện chia sẻ do rủi ro này. Điều gì xảy ra nếu một phiên bản mới của thư viện dùng chung giới thiệu một lỗi mới phá vỡ các ứng dụng cũ nhất định?

  • Liên kết tĩnh đảm bảo một ứng dụng độc lập hơn. Mặc dù các thư viện dùng chung có thể được tạo ra với tệp thực thi chính, nhưng chúng thường được gửi ở các vị trí dùng chung. Các ứng dụng được liên kết tĩnh dễ dàng hơn để đảm bảo "di động" theo nghĩa "không yêu cầu thay đổi tệp, thư mục hoặc cài đặt do HĐH sở hữu" (nghĩ thư mục Windows, sổ đăng ký, / v.v.).


Cảm ơn bạn đã cải thiện những lợi thế tôi muốn đề cập. Tuy nhiên, nếu bạn thấy hầu hết các gói được cung cấp bởi các bản phân phối Linux chẳng hạn, chúng không được biên dịch tĩnh. Nó không có vẻ rằng biên soạn tĩnh không được tán thành, ít nhất là từ một điểm bên ngoài xem.
Florian Margaine

1
Các thư viện động trên hầu hết mọi hệ điều hành hiện nay đều được phân trang theo nhu cầu. Chỉ có các trang thực sự được sử dụng là trong bộ nhớ. Nếu nhiều ứng dụng đang sử dụng cùng một chức năng, chúng sẽ chia sẻ bộ nhớ và sử dụng ít hơn trường hợp thư viện tĩnh. Nếu nhiều ứng dụng đang sử dụng các chức năng khác nhau trong cùng một thư viện, cả hai bộ chức năng sẽ được phân trang, có tác động xấp xỉ như cách tiếp cận tĩnh.
Alan Shutko

@AlanShutko Tôi đã đấu tranh và thử lại phần đó theo nhiều cách vì những gì bạn đã đề cập. Dù sao đi nữa, không có gì đảm bảo thực sự, ngay cả khi các hệ điều hành hiện đại thực tế mang lại hiệu quả của các thư viện dùng chung với chi phí tĩnh. Tôi sẽ chỉnh sửa lại.

@Snowman Tôi nghĩ điểm cơ bản là trên bất kỳ hệ điều hành thực tế nào cung cấp liên kết động (tôi không biết bất kỳ HĐH nào sử dụng liên kết động nhưng không yêu cầu phân trang) điểm thứ hai của bạn không giữ nước: bộ nhớ không thực sự được sử dụng trừ khi chức năng được sử dụng và bộ nhớ được sử dụng bởi thư viện động có thể được chia sẻ giữa các chương trình khác nhau bằng cách sử dụng nó, làm cho việc sử dụng bộ nhớ cho phiên bản động hiệu quả hơn thay vì ít hơn. Lý do thứ nhất và thứ ba của bạn là hợp lệ, nhưng tôi chỉ đơn giản là xóa lý do thứ hai: với bất kỳ giả định thực tế nào, điều đó chỉ sai.
Jules

@Jules Tôi đồng ý, đó là một điểm có vấn đề và có hiệu lực đáng ngờ trong các hệ điều hành hiện đại. Tôi đã gỡ bỏ nó.

1

Mỗi thư viện tĩnh và động đều có cách sử dụng riêng. Nhìn vào một ứng dụng trong phạm vi, chúng ta có một ý tưởng khác nhau về những gì cần thiết và những gì không.

Liên kết tĩnh đơn giản hóa việc triển khai ứng dụng. Không phải phát hiện và đối phó với các phiên bản khác nhau. Chỉ cần nướng và triển khai.

Lợi thế rõ ràng với các thư viện động là khả năng áp dụng các bản cập nhật độc lập.

Đây là một trong những lý do tôi ghê tởm maven và các nhà xây dựng dự án liên kết động tương tự khác cho java. Họ hy vọng một phiên bản thư viện duy nhất sẽ có sẵn tại một url nhất định mãi mãi. Không hiểu vấn đề xảy ra trong 10 năm khi không ai có thể biên dịch ứng dụng vì tất cả các nguồn và lọ đã biến mất.


Có bất kỳ lý do cụ thể nào khiến các chương trình sử dụng FooLib1.8có thể bao gồm mã cho thư viện đó trong gói thực thi của họ theo cách tiêu chuẩn, để cho phép một tiện ích nâng cấp được FooLib1.9cung cấp để nâng cấp hoặc hạ cấp không? Cách mã được lưu trữ trong Macintosh cổ điển sẽ khiến việc đó trở nên khá dễ dàng; Có lý do nào khiến các hệ thống ngày nay không thể làm điều đó tốt hơn nữa không?
supercat

@supercat bạn có nghĩa là mọi phiên bản của một thư viện nhất định sẽ có sẵn trên hệ thống? Không chắc tôi hiểu câu hỏi. Câu hỏi OP được hướng nhiều hơn vào các thư viện chia sẻ trên toàn hệ thống so với các thư viện tĩnh sẽ được đóng gói cùng nhau.
rất nhiều khoai tây chiên

Quan điểm của tôi là có một gói thực thi bao gồm tất cả các thư viện mà nó cần không phải loại trừ khả năng nâng cấp các thư viện chứa trong đó. Vì vậy, tôi không biết rằng tôi coi khả năng nâng cấp mọi thứ sau khi triển khai là một lợi thế của việc không đóng gói ứng dụng với các thư viện của nó.
supercat

Nếu giấy phép của một thư viện nhất định cho phép bạn phân phối nó với gói của bạn thì đó luôn là cách ưa thích để làm điều đó. Nó làm giảm số lượng phụ thuộc bên ngoài. Vì bạn sẽ phân phối mọi thứ sau đó một cơ chế nâng cấp hoặc vá sẽ hoạt động theo cùng một cách với tĩnh hoặc động. Vá thường dựa trên deltas nhị phân. Sẽ không có sự khác biệt.
rất nhiều khoai tây chiên
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.