2012-04-05 25 views
15

Nếu bạn đang cố gắng hiểu liên kết động, this question có thể sẽ được quan tâm.Hệ điều hành MacOS - cách liên kết thư viện động với đường dẫn tương đối bằng gcc/ld

Một trong những câu trả lời cho câu hỏi đó cung cấp một ví dụ tuyệt vời về tạo và sử dụng thư viện động. Dựa trên đó, tôi một số tập tin đơn giản:

main.c:

extern void someFunction (int x); 

int main (int argc, char** argv) { 
    someFunction(666); 
} 

mylibrary.c:

#include <stdio.h> 

void someFunction (int x) { 
    printf ("\nsomeFunction called with x=%d\n", x); 
} 

makefile:

main: mylibrary.c main.c 
    gcc -c mylibrary.c 
    gcc -dynamiclib -current_version 1.0 mylibrary.o -o libmylibrary.dylib 
    gcc -c main.c 
    gcc -v main.o ./libmylibrary.dylib -o main 

clean: 
    rm *.o 
    rm main 
    rm *.dylib 

Cho đến nay, tất cả mọi thứ hoạt động tốt . Nếu tôi thực hiện và sau đó nhập ./main tại dấu nhắc lệnh, tôi thấy kết quả mong đợi:

someFunction called with x=666 

Bây giờ, tôi muốn kết hợp mọi thứ lên một chút. Tôi đã tạo một thư mục hidelib, là thư mục con của thư mục chính của tôi. Và tôi thêm một dòng vào makefile của tôi:

main: mylibrary.c main.c 
    gcc -c mylibrary.c 
    gcc -dynamiclib -current_version 1.0 mylibrary.o -o libmylibrary.dylib 
    gcc -c main.c 
    mv libmylibrary.dylib hidelib  # this is the new line 

clean: 
    rm *.o 
    rm main 
    rm hidelib/*.* 

Bây giờ, tôi muốn thêm một dòng khác đến makefile vì vậy nó sẽ tìm libmylibrary.dylib trong thư mục con hidelib. Tôi muốn có thể chạy ./main trong cùng một cách. Làm thế nào tôi có thể làm điều đó?

CHỈNH SỬA: Cảm ơn bạn đã phản hồi. Có rất nhiều lựa chọn là tuyệt vời, nhưng một người mới bắt đầu chỉ muốn một tùy chọn cụ thể hoạt động. Đây là những gì tôi đang cố gắng cho dòng cuối cùng, nhưng rõ ràng tôi không hiểu điều gì đó. Các makefile thực hiện mà không có lỗi, nhưng tại thời gian chạy nó nói "thư viện không tìm thấy."

gcc main.o -rpath,'$$ORIGIN/hidelib' -lmylibrary -o main 

Trả lời

13

Một tùy chọn cụ thể hoạt động sẽ là đặt cờ install_name khi liên kết .dylib.

gcc -dynamiclib -install_name '$(CURDIR)/hidelib/libmylibrary.dylib' -current_version 1.0 mylibrary.o -o libmylibrary.dylib 

Sau đó, bạn chỉ có thể liên kết đến thư viện thường:

gcc main.o -L '$(CURDIR)/hidelib' -lmylibrary -o main 
7

Bạn có thể cần cờ biên giới/liên kết -L để thêm đường dẫn tìm kiếm cho thư viện.

Đang cố di chuyển mọi thứ sau khi liên kết, bạn sẽ cần biến môi trường dyld để tìm kiếm ở đâu. man dyld và bạn sẽ có thể nhận thêm thông tin về DYLD_LIBRARY_PATH và các biến môi trường khác.

Thông thường, mặc dù, bạn đặt tên cài đặt của thư viện để nối với đường một cái gì đó với cờ -install_name mối liên kết để cái gì đó như @rpath/mylibrary.dylib như giá trị, sau đó thiết lập các đường dẫn tìm kiếm chạy đường dẫn trên thực thi chính khi biên dịch với -rpath cờ đến @executable_path/hidelib.

Để biết thêm thông tin, hãy xem install_name_tool và các đối số -rpath & -install_name của ld.

Về cơ bản, có rất nhiều tùy chọn cho những gì bạn đang cố gắng làm.

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