2011-01-13 12 views
31

Tôi đã thực hiện một ứng dụng (thực thi) gọi một số dylib thành công, Tuy nhiên, các tập tin dylib và thực thi được trong thư mục khác nhau. Tôi đã thêm thư mục chứa các tệp dylib vào biến môi trường $ PATH, tuy nhiên, nó vẫn không tải. Tôi sao chép tất cả các tập tin dylib để thực thi, chương trình cuối cùng chạy. Điều này xác nhận các tập tin dylib không có vấn đề. Tuy nhiên, Làm thế nào tôi có thể yêu cầu hệ điều hành tìm thấy nó? Trong cửa sổ, tôi chỉ cần thêm đường dẫn thư mục chứa các tệp dll vào $ PATH. Tôi cần làm gì cho Mac OS X? Cảm ơn rất nhiều!Làm thế nào để sử dụng dylib trong Mac OS X (C++)

+4

Kiểm tra các phụ thuộc của ứng dụng của bạn bằng cách sử dụng 'otool -L app'. Nếu chúng được hardcoded như đường dẫn tuyệt đối sau đó sửa đổi chúng bằng cách sử dụng 'install_name_tool -change cũ tập tin mới' để trở thành tương đối một. Sau đó, trình liên kết có thể tìm thấy một thư viện trong biến môi trường 'DYLD_LIBRARY_PATH' của bạn. – aponomarenko

Trả lời

2

Nếu dylib ở vị trí được chỉ định bởi INSTALL_NAME của thư viện, nó sẽ chỉ hoạt động *.

Nếu không, bạn có thể thêm vị trí của dylib vào DYLD_LIBRARY_PATH. Bạn có thể muốn đọc số dyld documentation.

*) để hoàn toàn chính xác, nó cần phải ở DYLD_ROOT_PATH/INSTALL_NAME, nhưng phiền phức với DYLD_ROOT_PATH là khá hiếm.

+0

Xin lỗi, "INSTALL_NAME của thư viện" là gì? Tôi thêm DYLD_LIBRARY_PATH và nó không hoạt động, do đó, bối rối. –

+0

Bạn cần xuất biến: xuất DYLD_LIBRARY_PATH =/usr/local/lib' – Michel

13

Bạn cần đặt biến môi trường DYLD_LIBRARY_PATH.

Từ dyld man page:

 This is a colon separated list of directories that contain libraries. The dynamic linker 
     searches these directories before it searches the default locations for libraries. It allows 
     you to test new versions of existing libraries. 

     For each library that a program uses, the dynamic linker looks for it in each directory in 
     DYLD_LIBRARY_PATH in turn. If it still can't find the library, it then searches DYLD_FALL- 
     BACK_FRAMEWORK_PATH and DYLD_FALLBACK_LIBRARY_PATH in turn. 
+0

cảm ơn! Tôi cũng tìm thấy điều này bởi google, tôi đã thiết lập DYLD_LIBRARY_PATH, tuy nhiên, nó không hoạt động, vấn đề vẫn còn đó! Tôi rất bối rối –

+0

Tôi vừa thử nó và nó hoạt động tốt trên máy Mac của tôi. – EmeryBerger

+0

Xin chào, EmeryBerger, bạn có phải là biến DYLD_LIBRARY_PATH ban đầu trống không. của tôi là. Tôi không biết nếu điều này là sai ở nơi đầu tiên. –

34

Sau khi đọc các trang liên kết Justin cung cấp, tôi đã thành công có thể sử dụng thẻ để thay đổi @executable_path install_name dylib tôi để trỏ đến cùng một thư mục nơi thực thi của tôi nằm.

@executable_path Đường dẫn tuyệt đối gây phiền nhiễu. Đôi khi bạn muốn nhúng khung vào ứng dụng thay vì phải cài đặt khung vào/Thư viện hoặc một vị trí tương tự.

Giải pháp của Mac là @executable_path. Đây là mã thông báo ma thuật , khi được đặt ở đầu tên cài đặt của thư viện, được mở rộng đến đường dẫn của tệp thực thi đang tải nó, trừ đi thành phần cuối cùng . Ví dụ: giả sử liên kết Bar.app chống lại Foo.framework. Nếu Bar.app được cài đặt trong/Applications, @executable_path sẽ mở rộng thành /Applications/Bar.app/Contents/MacOS. Nếu bạn định nhúng khung trong Nội dung/Khung, thì bạn chỉ có thể đặt tên cài đặt của Foo.framework thành @executable_path /../ Frameworks/Foo.framework/Phiên bản/A/Foo. Liên kết động sẽ mở rộng đến /Ứng dụng /Bar.app/Contents/MacOS/../Frameworks/Foo.framework/Versions/A/Foo và sẽ tìm thấy khung ở đó.

http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html

Tôi sẽ chứng minh với một ví dụ.

Hãy nói rằng tôi có thực thi /opt/local/bin sau/chuyển đổi và dylibs của nó là trong /opt/local/lib. Tôi muốn sao chép nó sang thư mục khác và tải nó xuống thư mục tương tự như nơi tôi đã sao chép tệp thực thi.

> mkdir ~/tmp/bin 
> cp /opt/local/bin/convert ~/tmp/bin 

Nhận một danh sách các tập tin thực thi dylibs

> otool -L ~/tmp/bin/convert 
~/tmp/bin/convert: 
    /opt/local/lib/libtiff.3.dylib (compatibility version 13.0.0, current version 13.5.0) 
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0) 
    /opt/local/lib/libjpeg.8.dylib (compatibility version 12.0.0, current version 12.0.0) 
    /opt/local/lib/libfontconfig.1.dylib (compatibility version 6.0.0, current version 6.4.0) 
    /opt/local/lib/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0) 
    /opt/local/lib/libfreetype.6.dylib (compatibility version 15.0.0, current version 15.0.0) 
    /opt/local/lib/libexpat.1.dylib (compatibility version 7.0.0, current version 7.2.0) 
    /opt/local/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.6) 
    /opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.6) 
    ... 

Tôi chỉ quan tâm đến các dylibs trong /opt/local/lib dir, vì vậy chúng tôi kéo ra chỉ dylibs trong /chọn . Tôi muốn giữ nguyên tất cả các tham chiếu dylib khác, đặc biệt là các công cụ /usr/lib/libSystem.

> DYLIBS=`otool -L ~/tmp/bin/convert | grep "/opt" | awk -F' ' '{ print $1 }'` 

Sao chép tất cả các dylibs thực thi tham chiếu đến cùng một thư mục nơi tệp thực thi được sao chép vào.

> for dylib in $DYLIBS; do cp $dylib ~/tmp/bin/; done; 

Sử dụng install_name_tool để thay đổi tên cài đặt của tất cả các dylibs chúng tôi kéo ra ở bước trên, và thay thế chúng bằng cách thêm vào trước các @executable_path tên dylib. Điều này sẽ làm cho trình liên kết động tìm kiếm dylib trong cùng thư mục với vị trí thực thi.

> for dylib in $DYLIBS; do install_name_tool -change $dylib @executable_path/`basename $dylib` ~/tmp/bin/convert; done; 

Xác nhận rằng tên cài đặt đã được thay đổi và rằng libSystem vẫn trỏ đến /usr/lib/libSystem.

> otool -L ~/tmp/bin/convert 
~/tmp/bin/convert: 
    @executable_path/libtiff.3.dylib (compatibility version 13.0.0, current version 13.5.0) 
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0) 
    @executable_path/libjpeg.8.dylib (compatibility version 12.0.0, current version 12.0.0) 
    @executable_path/libfontconfig.1.dylib (compatibility version 6.0.0, current version 6.4.0) 
    @executable_path/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0) 
    @executable_path/libfreetype.6.dylib (compatibility version 15.0.0, current version 15.0.0) 
    @executable_path/libexpat.1.dylib (compatibility version 7.0.0, current version 7.2.0) 
    @executable_path/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.6) 
    @executable_path/libz.1.dylib (compatibility version 1.0.0, current version 1.2.6) 
    ... 
+0

Lưu ý rằng có vẻ như bạn cũng phải thực hiện điều này cho mỗi tệp thư viện, vì chúng cũng có thể chứa liên kết đến đường dẫn tuyệt đối – Claudiu