2008-10-23 41 views
17

Tôi đang cố gắng liên kết một RPATH chứa chuỗi đặc biệt $ ORIGIN vào tệp thi hành được xây dựng bằng GCC với Mã :: Blocks IDE. Tôi đã chỉ định

-Wl,-R$ORIGIN 

trong các tùy chọn liên kết cho dự án, nhưng các dòng lệnh đầu ra để GCC là sai (tước cho rõ ràng):

g++ -Wl,-R 

cách chính xác để xác định lập luận này là gì cho Code :: Blocks?

+0

Có liên quan, nhưng không chỉ định Mã :: Khối: http://stackoverflow.com/q/6324131/257299 – kevinarpe

Trả lời

34

Bất kỳ ai quyết định tạo mã thông báo $ ORIGIN đều là một tên khốn xấu xa xứng đáng có vị trí đặc biệt trong lập trình địa ngục. Vì '$' là một ký tự đặc biệt đối với bash và các ngôn ngữ kịch bản khác như tạo, nó xoay mọi thứ trừ khi cẩn thận thoát ra. Thậm chí tệ hơn, tùy thuộc vào môi trường xây dựng bạn đang sử dụng, các chi tiết cụ thể về cách thoát đúng cách có thể sẽ thay đổi.

Trong bash, bạn cần phải dính vào một dấu gạch chéo ở phía trước của $:

-Wl,-R\$ORIGIN 

Code :: Blocks dường như cũng xử lý các $ đặc biệt. Sau đó, bất kỳ bộ điều khiển con nào Code :: Blocks gửi lệnh để xử lý dấu gạch chéo ngược là đặc biệt. Vì vậy, cả dấu gạch chéo ngược và $ cần phải được tăng gấp đôi để thoát khỏi đúng cách. Do đó, trong Code :: thiết lập mối liên kết Blocks, bạn cần phải xác định:

-Wl,-R\\$$ORIGIN 

... mà kết quả đầu ra:

-Wl,-R\\$ORIGIN 

... để xây dựng nhật ký, nhưng vỏ thực sự được gửi:

-Wl,-R\$ORIGIN 

... như đã đề cập ở trên tạo ra kết quả mong muốn.

Thật là một nỗi đau.

+6

+1 chỉ để nhận xét về tên khốn xấu ... vấn đề này đã khiến tôi đau đớn – chotchki

+0

Nhận xét hoàn hảo , anh ta nên thối rữa trong địa ngục .. với 40 succubus thăm dò anh ta lol. –

+0

Có cách nào, được xây dựng để thực thi, thay đổi RPATH của nó không? Vì đây chỉ là một chuỗi trong các bảng ELF, nó có vẻ không hợp lý. Đặt rpath thành $ ORIGIN/yada/yada có vẻ như tôi là thứ bạn muốn thêm vào một số tập lệnh có sẵn (có thể phức tạp khủng khiếp) và nếu họ cung cấp cách gửi tùy chọn cho trình liên kết, thì tuyệt vời, nhưng , như đã thảo luận, bạn phải đối phó với địa ngục thoát (có thể dễ dàng hơn để làm cho wrapper 'ld' của riêng bạn để lén nó trong). OTOH sửa đổi đường rạch trên các kết quả sau khi khói bị xóa? Không quá khó. Nếu, đó là, có một tiện ích có thể làm điều đó ... – greggo

15

Ngoài câu trả lời kblucks để giải quyết câu hỏi cho Mã: Blocks .... Đối với những người như tôi đã tình cờ tìm thấy cách thực hiện điều này bằng Make. Bí quyết là sử dụng một $ dấu thêm như một nhân vật chạy thoát và gửi kèm nó với dấu ngoặc kép:

-Wl,-R,'$$ORIGIN/../lib' 

Full lời giải thích có thể có ở đây: Using ORIGIN for a dynamic runtime library search path

1

Nếu thực thi của bạn đang được xây dựng bởi một khổng lồ môi trường tập lệnh phức tạp không phải do bạn tạo ra và bạn không muốn nghiên cứu về điều đó, hãy thử chạy với setenv LD_RUN_PATH='$ORIGIN/../lib'; nếu điều đó không hiệu quả, cách tiếp cận thực dụng là tạo trình bao bọc cho ld:

#!/bin/sh 
exec /usr/bin/ld -R '$ORIGIN/../lib' "[email protected]" 

... sau đó thực hiện xây dựng với nhánh đó trên đường dẫn. Trong thực tế, nó có thể được gọi để xây dựng các tệp .so hoặc các tệp thi hành khác, vì vậy bạn có thể cần phải làm cho tập lệnh phức tạp hơn này quyết định có nên chèn RPATH hay không. HOẶC, chạy xây dựng mà không có điều này, và với, và chọn anh đào.

(ở đây "/ usr/bin/ld" là ld bình thường đã được chạy, có thể ở một nơi khác. Gcc có thể không nhận ld từ đường dẫn, xem các biến môi trường gcc để ghi đè điều đó. khác nhau. Chỉ sử dụng một lần. Không được bảo đảm kém khủng khiếp hơn bất kỳ cách tiếp cận nào khác).

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