2015-11-04 22 views
9

Chỉnh sửa: Tôi đã giải quyết vấn đề này, giải pháp bên dưới.Tại sao tôi không thể ghi đè đường dẫn tìm kiếm của thư viện động với LD_LIBRARY_PATH?

Tôi đang tạo mã trong một cụm máy tính dùng chung cho máy tính khoa học, do đó tôi chỉ có thể kiểm soát tệp trong thư mục chính của mình. Mặc dù tôi đang sử dụng fftw như một ví dụ, tôi muốn hiểu lý do cụ thể, tại sao nỗ lực của tôi để thiết lập LD_LIBRARY_PATH không hoạt động.

tôi xây dựng các thư viện fftw và fftw_mpi trong thư mục nhà của tôi như thế này

./configure --prefix=$HOME/install/fftw --enable-mpi --enable-shared 
make install 

Nó xây dựng tốt, nhưng trong cài đặt/fftw/lib, tôi thấy tươi xây dựng libfftw3_mpi.so liên kết đến phiên bản sai của thư viện fftw.

$ ldd libfftw3_mpi.so |grep fftw 
    libfftw3.so.3 => /usr/lib64/libfftw3.so.3 (0x00007f7df0979000) 

Nếu bây giờ tôi cố gắng để thiết lập LD_LIBRARY_PATH chỉ đúng vào thư mục này, nó vẫn thích thư viện sai:

$ export LD_LIBRARY_PATH=$HOME/install/fftw/lib 
$ ldd libfftw3_mpi.so |grep fftw 
    libfftw3.so.3 => /usr/lib64/libfftw3.so.3 (0x00007f32b4794000) 

Chỉ khi tôi dứt khoát sử dụng LD_PRELOAD, tôi có thể ghi đè lên hành vi này. Tôi không nghĩ rằng LD_PRELOAD là một giải pháp thích hợp mặc dù.

$ export LD_PRELOAD=$HOME/install/fftw/lib/libfftw3.so.3 
$ ldd libfftw3_mpi.so |grep fftw 
    $HOME/install/fftw/lib/libfftw3.so.3 (0x00007f5ca3d14000) 

Đây là những gì tôi sẽ phải chờ đợi, một thử nghiệm nhỏ được thực hiện trong máy tính để bàn Ubuntu, nơi tôi cài đặt fftw đến/usr/lib đầu tiên, và sau đó ghi đè lên đường tìm kiếm này với LD_LIBRARY_PATH.

$ export LD_LIBRARY_PATH= 
$ ldd q0test_mpi |grep fftw3 
    libfftw3.so.3 => /usr/lib/x86_64-linux-gnu/libfftw3.so.3 
$ export LD_LIBRARY_PATH=$HOME/install/fftw-3.3.4/lib 
$ ldd q0test_mpi |grep fftw3 
    libfftw3.so.3 => $HOME/install/fftw-3.3.4/lib/libfftw3.so.3 

Tóm lại: Tại sao thư viện libfft3_mpi vẫn tìm thấy thư viện fftw3 động sai? Đường dẫn tìm kiếm này được mã hóa cứng ở đâu theo cách được ưu tiên hơn LD_LIBARY_PATH? Tại sao đây không phải là trường hợp trong một máy tính khác?

Tôi đang sử dụng các trình biên dịch intel 13.1.2, mkl 11.0.4.183 và openmpi 1.6.2 nếu điều này quan trọng.

Chỉnh sửa: Cảm ơn tất cả các câu trả lời. Với sự giúp đỡ của những người đó, chúng tôi đã có thể cô lập vấn đề với RPATH, và từ đó, sự hỗ trợ cụm đã có thể tìm ra vấn đề. Tôi chấp nhận câu trả lời đầu tiên, nhưng cả hai câu trả lời đều tốt.

Lý do, tại sao điều này rất khó tìm ra, là chúng tôi không biết rằng các trình biên dịch thực sự là các kịch bản trình bao bọc, thêm các thứ vào dòng lệnh trình biên dịch. Đây là một phần của thư trả lời từ sự hỗ trợ:

[Biên dịch] trải qua trình bao bọc trình biên dịch của chúng tôi. Chúng tôi thực hiện RPATH-ing theo mặc định vì nó giúp hầu hết người dùng chạy đúng công việc của mình mà không tải LD-LIBRARY_PATH v.v. Tuy nhiên, chúng tôi loại trừ một số đường dẫn thư viện nhất định từ RPATH mặc định bao gồm/lib,/lib64/proj /home v.v. Trước đó,/usr/lib64 không bị loại trừ do nhầm lẫn (chủ yếu). Bây giờ chúng ta đã thêm đường dẫn đó vào danh sách loại trừ.

Trả lời

12

Từ

Khi giải quyết phụ thuộc đối tượng chia sẻ, mối liên kết động đầu tiên kiểm tra mỗi chuỗi phụ thuộc để xem nếu nó chứa một dấu gạch chéo ( điều này có thể xảy ra nếu một tên đường dẫn đối tượng chia sẻ chứa dấu gạch chéo là được chỉ định tại thời gian liên kết).Nếu tìm thấy dấu gạch chéo, thì chuỗi phụ thuộc được hiểu là tên đường dẫn (tương đối hoặc tuyệt đối) và đối tượng được chia sẻ được tải bằng tên đường dẫn đó.

Nếu một sự phụ thuộc đối tượng chia sẻ không chứa một dấu gạch chéo, sau đó nó là tìm kiếm theo thứ tự sau:

o (ELF chỉ) Sử dụng các thư mục quy định tại các DT_RPATH động phần thuộc tính của nhị phân nếu hiện tại và thuộc tính DT_RUNPATH không tồn tại. Sử dụng DT_RPATH không được chấp nhận.

o Sử dụng biến môi trường LD_LIBRARY_PATH. Ngoại trừ nếu thực thi là tập hợp nhị phân ID người dùng/nhóm ID, trong trường hợp này, bị bỏ qua.

o (chỉ ELF) Sử dụng các thư mục được chỉ định trong thuộc tính phần động DT_RUNPATH động của nhị phân nếu có.

o Từ tệp bộ nhớ cache /etc/ld.so.cache, trong đó có một danh sách các đối tượng được chia sẻ ứng viên được tìm thấy trong đường dẫn thư viện được biên soạn trước đây. Tuy nhiên, nếu nhị phân được liên kết với tùy chọn liên kết -z nodeflib, các đối tượng được chia sẻ trong đường dẫn mặc định là bị bỏ qua. Các đối tượng dùng chung được cài đặt trong khả năng phần cứng Các thư mục (xem bên dưới) được ưu tiên cho các đối tượng dùng chung khác.

o Trong đường dẫn/lib mặc định và sau đó/usr/lib. (Trên một số kiến ​​trúc 642 bit64 bit, đường dẫn mặc định cho đối tượng chia sẻ 64 bit là /lib64 và sau đó/usr/lib64.) Nếu nhị phân được liên kết với tùy chọn liên kết -z nodeflib, bước này bị bỏ qua.

  • với readelf readelf -d libfftw3_mpi.so bạn có thể kiểm tra nếu lib của bạn có chứa như một thuộc tính trong phần năng động.

  • với export LD_DEBUG=libs bạn có thể gỡ lỗi các đường dẫn tìm kiếm sử dụng để tìm libs của bạn

  • với chrpath -r<new_path> <executable> các rPath có thể thay đổi

+0

Thật vậy, với chính mình, có vẻ như thực sự/usr/lib64 là trước/home/USER/install/fftw/lib trong biến được gọi là RPATH. Bây giờ vấn đề vẫn còn, đó là/usr/lib64 đã có trước/fftw/lib như thế nào. '$ readelf -d libfftw3_mpi.so | grep RPATH 0x000000000000000f (RPATH) Đường dẫn thư viện: [/software/intel/composer_xe_2013.4.183/compiler/lib/intel64:/usr/lib:/usr/lib/gcc/x86_64-redhat-linux/4.4.4:/usr/lib64:/home/USER/install/fftw/lib] ' –

+0

rpath được thêm vào lúc biên dịch. Tôi không biết lib fftw nhưng có thể có cờ cấu hình '--disable-rpath'. để thay đổi đường chạy, bạn có thể sử dụng 'chrpath -r ' để thay đổi đường đi trong thư viện – bonoparte

2

tôi thấy hai lý do có thể cho việc này.

Đầu tiên, libfftw3_mpi.so có thể được liên kết với /usr/lib64/RPATH. Trong trường hợp đó, việc cung cấp LD_LIBRARY_PATH sẽ không có hiệu lực. Để kiểm tra xem đó có phải là trường hợp của bạn hay không, hãy chạy readelf -d libfftw3_mpi.so | grep RPATH và xem nó có /usr/lib64/ làm đường dẫn thư viện hay không. Nếu có, hãy sử dụng tiện ích chrpath để thay đổi hoặc xóa tiện ích đó.

Hoặc, bạn có thể đang chạy một hệ thống không hỗ trợ LD_LIBRARY_PATH ở tất cả (như HP-UX).

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