2012-12-21 39 views
10

Tôi đang xây dựng một chương trình với autoconf, automake và libtool. Tác phẩm của tôi yêu cầu tôi liên kết tĩnh (hầu hết) thư viện. Đây không phải là một vấn đề trong quá khứ vì tôi có thể liên kết tĩnh mọi thứ với -all-static. Bây giờ nó là một vấn đề bởi vì tôi phải sử dụng một thư viện mà là chỉ năng động; nó đã được trao cho chúng tôi bởi một bên thứ ba, và chúng tôi không có nguồn.Làm cách nào để người dùng autotools chỉ định kết hợp giữa liên kết tĩnh và động?

Tất nhiên, -all-static giờ đây khiến quá trình xây dựng thất bại. Có thể yêu cầu libtool liên kết tĩnh mọi thứ, ngoại trừ thư viện này không? Có thể có libtool thực hiện bất kỳ sự kết hợp nào giữa liên kết động và động hay là tất cả hoặc không có gì?

Cho đến giờ tôi đã thử tạo một thư viện tiện lợi với LDFLAGS = -static, phụ thuộc vào thư viện tôi muốn liên kết tĩnh. Nhưng libtool không nối các thư viện tĩnh, như tôi đã hy vọng. Chương trình tùy thuộc vào thư viện tiện dụng vẫn tự động liên kết mọi thứ.

Tôi cũng đã thử --disable-shared, nhưng điều đó không ảnh hưởng đến bản dựng.


Những câu hỏi tương tự, nhưng không thực sự trả lời câu hỏi của tôi:

Force linking a static library into a shared one with Libtool

Is it possible to link some — but not all — libraries statically with libtool?

(Tôi không muốn xóa các thư viện được chia sẻ từ hệ thống của tôi, và chỉ định đường dẫn đầy đủ cho mọi thứ khó có thể tốt hơn là liên kết bằng tay, nhưng có lẽ đó là cách duy nhất.)

Trả lời

10

Bạn đã làm n ot xác định hệ điều hành, nhưng chúng ta hãy giả định rằng nó là một Unix/Linux/OSX tương đối gần đây. Nếu không, hãy bỏ qua cảnh báo sau.

Trước khi trả lời, bạn nên biết rằng việc trộn mã tĩnh và chia sẻ trên hầu hết các hệ thống dựa trên ELF (Unix/Linux) là có vấn đề. Một lý do là vì nó có thể dẫn đến mã không đồng bộ nếu bạn quên liên kết lại một phụ thuộc được cập nhật. Khác là do bản chất của mã tĩnh so với PIC. Đây là lý do tại sao libtool cố gắng ngăn cản nó.

Điều đó đang được nói, trong Makefile.am (giả sử chương trình cuối cùng của bạn là foo và thư viện được chia sẻ là):

. 
    . 
    . 
    foo_SOURCES = foo.c abc.c def.c hij.c 
    foo_LDFLAGS = -all-static -Wl,-Bdynamic,-L/path/to,-lshared,-Bstatic 
    foo_LDADD = -L../path/to -lbar -lbaz 

Điều quan trọng ở đây là libtool cho phép bạn ngắn mạch kiểm tra và Cờ -static của GNU gcc (được sử dụng bởi libtool) bằng cách chuyển trực tiếp -Wl, đối số cho trình liên kết (GNU ld). Để đặt dấu cách giữa các đối số, dấu phân cách bằng dấu phẩy , được sử dụng.

Cả hai -Bstatic-Bdynamic được ghi lại trong GNU ld's info pages cũng như màn hình trợ giúp. Một lần nữa, vì bạn không đề cập đến gói os hoặc trình biên dịch đang được sử dụng, tôi giả sử GNU gcc và GNU ld trên Linux. Bạn có thể muốn xác minh bằng cách sử dụng ld --help để tự mình xem. Nếu vì một lý do nào đó, nó không phải là GNU ld, thì bạn sẽ cần phải tìm các cờ tương đương với -Bstatic-Bdynamic, thay thế khi thích hợp.

+1

Tác phẩm này hoạt động nhưng mất tính linh hoạt.Tôi không cần xây dựng năng động, nhưng nếu tôi từng làm thì tôi sẽ cần phải chỉnh sửa một số 'Makefile.am', phải không? Điều này cũng gây ra vấn đề với các macro như 'AC_CHECK_LIB' (chỉ thêm' -l' vào 'LIBS'), nhưng tôi đoán đó là điều được mong đợi. – tprk77

+2

Tôi đã đưa ra cách tiếp cận đơn giản nhất có thể. Tuy nhiên, đối với một cái gì đó ưa thích, bạn có thể kéo cờ vào 'configure.ac' của bạn. Khi đó, bạn có thể thêm 'DYNLIBS =" - Wl, -Bdynamic, -L/đường dẫn /,, chia sẻ, -Bstatic "' với một cuộc gọi đến 'AC_SUBST ([DYNLIBS])'. Sau đó, tất cả những gì bạn cần làm là gọi '$ (DYNLIBS)' trong 'Makefile.am' của bạn. Điều này sẽ giúp bạn kiểm soát nhiều hơn, nhưng hãy nhớ rằng 'AC_CHECK_LIBS' không kiểm tra các lib tĩnh và động. Đó có phải là những gì bạn muốn hoặc có cái gì khác mà sẽ làm cho nó linh hoạt hơn? – NickW

+0

Vâng tôi nghĩ điều đó sẽ hiệu quả, cảm ơn! – tprk77

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