2014-07-07 22 views
5

Tôi đã gặp một vấn đề kỳ lạ nhất mà tôi từng gặp. Tôi đang biên dịch một ứng dụng cho CPU ARM với Linux trên bo mạch. Tôi đang sử dụng buildroot và tất cả đều tốt cho đến khi tôi cố gắng chạy ứng dụng trên mục tiêu: Tôi nhận được -sh: ./hw: not found. Ví dụ:"sh: ./ <file> không tìm thấy" lỗi khi cố gắng thực thi một tệp

$ cat /tmp/test.cpp 
#include <cstdio> 
#include <vector> 

int main(int argc, char** argv){ 
     printf("Hello Kitty!\n"); 
     return 0; 
} 
$ ./arm-linux-g++ -march=armv7-a /tmp/test.cpp -o /tftpboot/hw 

tải tệp thi hành xuống đích; sau đó phát hành trên mục tiêu:

# ./hw 
-sh: ./hw: Permission denied 
# chmod +x ./hw 
# ./hw 
-sh: ./hw: not found 
# ls -l ./hw 
-rwxr-xr-x 1 root  root   6103 Jan 1 03:40 ./hw 

Có nhiều với nó: khi xây dựng với trình biên dịch distro, như arm-linux-gnueabi-g++ -march=armv7-a /tmp/test.cpp -o /tftpboot/hw, ứng dụng chạy tốt!

Tôi đã so sánh các tệp thi hành thông qua readelf -a -W /tftpboot/hw, nhưng không nhận thấy nhiều sự thiếu defference. I pasted both outputs here. Điều duy nhất tôi nhận thấy, là các dòng Version5 EABI, soft-float ABIVersion5 EABI. Tôi đã thử xóa sự khác biệt bằng cách chuyển một trong hai số -mfloat-abi=softfp-mfloat-abi=soft, nhưng trình biên dịch dường như bỏ qua nó. Tôi cho rằng mặc dù, điều này không thực sự quan trọng, như trình biên dịch thậm chí không cảnh báo.

Tôi cũng nghĩ, có lẽ sh xuất ra lỗi này nếu tệp thực thi không tương thích theo một cách nào đó. Nhưng trên máy tính chủ của tôi, tôi thấy lỗi khác trong trường hợp này, ví dụ .:

$ sh /tftpboot/hw 
/tftpboot/hw: 1: /tftpboot/hw: Syntax error: word unexpected (expecting ")") 
+0

tương tự http://stackoverflow.com/questions/14535897/buildroot-file-system-cross-compiling-dynamically-linked-application-fails-bu –

Trả lời

7

sh in lỗi này lạ vì nó đang cố gắng để chạy chương trình của bạn như một kịch bản vỏ!

Lỗi của bạn ./hw: not found có thể do liên kết động (trình thông dịch AKA ELF) không được tìm thấy. Hãy thử biên dịch nó như là một chương trình tĩnh với -static hoặc chạy nó với bộ nạp động của bạn: # /lib/ld-linux.so.2 ./hw hoặc một cái gì đó tương tự.

Nếu vấn đề là bộ nạp động được đặt tên khác nhau trong công cụ chuỗi và trong môi trường thời gian chạy của bạn, bạn có thể sửa chữa nó:

  • Trong môi trường runtime: với một liên kết tượng trưng.
  • Trong công cụ chuỗi: sử dụng -Wl,--dynamic-linker=/lib/ld-linux.so.2
+2

Có , tùy chọn '-static' thực hiện thủ thuật! Cảm ơn nhiều! Chỉ cần tò mò - nếu bạn biết, xin vui lòng, cho tôi biết: những gì các thư viện nên đã được liên kết ở đó, và tại sao các tập tin đã được xử lý như một kịch bản cho đến khi tôi liên kết tĩnh? Hệ thống có nhìn thấy chữ ký "ELF" trong tệp không? –

+2

@YagamyLight: Vấn đề không phải là thư viện mà là trình liên kết động, đó là chương trình tải các tệp thi hành động. Trong Linux, nó thường là '/ lib/ld-linux *'. Bạn có thể thấy nó là gì với 'objdump -s -j/bin/ls', là'/bin/ls' một tệp thi hành động hoạt động. – rodrigo

+2

@YagamyLight: Tệp được coi là tập lệnh vì đó là những gì 'sh' thực hiện với đối số đầu tiên của nó: coi đó là tập lệnh. Để coi nó như một lệnh (và một chương trình có thể) sử dụng 'sh -c./Hw'. Nhưng sau đó, bạn có thể chỉ cần viết './Hw'. – rodrigo

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