Gần đây tôi đã chiến đấu với một số vấn đề đang cố gắng biên dịch thư viện nguồn mở trên máy Mac phụ thuộc vào thư viện khác và có một số lỗi về kiến trúc thư viện không tương thích. Ai đó có thể giải thích khái niệm đằng sau việc biên dịch một chương trình C cho một kiến trúc cụ thể không? Tôi đã thấy cờ trình biên dịch -arch
trước đây và đã thấy các giá trị được truyền cho nó như ppc
, i386
và x86_64
mà tôi cho rằng ánh xạ tới "ngôn ngữ" của CPU, nhưng sự hiểu biết của tôi dừng ở đó. Nếu một chương trình sử dụng một kiến trúc cụ thể, thì tất cả các thư viện mà nó tải cần phải có cùng kiến trúc không? Làm thế nào tôi có thể nói kiến trúc nào cho một chương trình/quy trình cụ thể đang chạy theo?Biên dịch chương trình C với kiến trúc cụ thể
Trả lời
Ai đó có thể giải thích khái niệm đằng sau việc biên dịch chương trình C cho một kiến trúc cụ thể không?
Có. Ý tưởng là dịch C thành một chuỗi các lệnh máy gốc, có chương trình được mã hóa thành dạng nhị phân. Ý nghĩa của "kiến trúc" ở đây là "kiến trúc bộ chỉ dẫn", đó là cách các lệnh được mã hóa theo dạng nhị phân. Ví dụ, mọi kiến trúc đều có cách mã hóa riêng cho một lệnh có thêm hai số nguyên.
Lý do để biên dịch thành lệnh máy là chúng chạy rất nhanh.
Nếu một chương trình sử dụng kiến trúc cụ thể, tất cả thư viện mà nó tải cũng cần phải có cùng kiến trúc không?
Có. (Ngoại lệ tồn tại nhưng chúng rất hiếm.)
Làm cách nào để biết cấu trúc của một chương trình/quy trình cụ thể đang hoạt động?
Nếu một quá trình đang chạy trên phần cứng của bạn, nó đang chạy trên kiến trúc bản địa mà trên Unix bạn có thể khám phá bằng cách chạy lệnh uname -m
, mặc dù đối với người đọc người đầu ra từ uname -a
có thể nhiều thông tin hơn.
Nếu bạn có một thực thi nhị phân hoặc một thư viện chia sẻ (.so tập tin), bạn có thể khám phá kiến trúc của nó bằng cách sử dụng file
lệnh:
% file /lib/libm-2.10.2.so
/lib/libm-2.10.2.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
% file /bin/ls
/bin/ls: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, stripped
Bạn có thể thấy rằng những mã nhị phân đã được biên soạn cho người già Kiến trúc 80386, mặc dù phần cứng của tôi là một i686 hiện đại hơn. I686 (Pentium Pro) tương thích ngược với 80386 và chạy 80386 nhị phân cũng như các tệp nhị phân gốc. Để làm cho khả năng tương thích ngược này có thể xảy ra, Intel đã gặp rất nhiều rắc rối và chi phí — nhưng họ thực tế đã dồn vào thị trường trên các CPU máy tính để bàn, vì vậy nó rất đáng giá!
Để xây dựng cho một kiến trúc khác với bản gốc của CPU, bạn sẽ cần một trình biên dịch chéo, có nghĩa là mã được tạo không thể chạy tự nhiên trên máy bạn đang ngồi. GCC có thể làm điều này tốt. Để tìm ra kiến trúc mà chương trình được xây dựng để kiểm tra lệnh tập tin. Trong các hệ thống dựa trên Linux ít nhất, một chương trình 32-bit x86 sẽ yêu cầu lib 32 bit x86 đi cùng với nó. Tôi đoán nó giống nhau đối với hầu hết các hệ điều hành.
Một điều có thể gây nhầm lẫn ở đây là nền tảng Mac có thứ mà họ gọi là universal binary, thực sự là hai tệp nhị phân trong một tệp lưu trữ, một cho intel và một cho kiến trúc ppc. Máy tính của bạn sẽ tự động quyết định cái nào sẽ chạy. Bạn có thể (đôi khi) chạy nhị phân cho kiến trúc khác trong chế độ mô phỏng, và một số kiến trúc là supersets của những người khác (tức là mã i386 sẽ thường chạy trên i486, i586, i686, v.v.) nhưng phần lớn mã duy nhất bạn có thể chạy là mã cho kiến trúc bộ vi xử lý của bạn.
Để biên dịch chéo, không chỉ chương trình, mà tất cả các thư viện mà nó sử dụng, cần phải tương thích với bộ xử lý đích. Đôi khi điều này có nghĩa là có một trình biên dịch thứ hai được cài đặt, đôi khi nó chỉ là một câu hỏi có mô-đun bổ sung phù hợp cho trình biên dịch khả thi. Trình biên dịch chéo cho gcc is actually a seperate executable, though it can sometimes be accessed via a command line switch. Trình biên dịch chéo gcc cho các kiến trúc khác nhau có nhiều khả năng cài đặt riêng biệt.
Có ldd trợ giúp trong trường hợp này không?
- 1. biên dịch C++ thành chương trình "thực"
- 2. Trình biên dịch/trình biên dịch BCPL cho hệ điều hành và kiến trúc hiện tại?
- 3. Trình biên dịch/trình biên dịch/trình biên dịch C++
- 4. biên dịch chương trình java
- 5. C tối ưu hóa cấu trúc trình biên dịch
- 6. Lỗi biên dịch Xcode iOS6: Không có kiến trúc
- 7. Biên dịch và chạy chương trình C trong Emacs
- 8. Trình biên dịch biên dịch trong C#
- 9. không thể biên dịch chương trình JNI rJava
- 10. Bạn có thể tìm ra trình biên dịch nào được sử dụng để biên dịch chương trình không?
- 11. Có một lá cờ trình biên dịch cho biết thiếu kiến trúc armv7s
- 12. Android NDK: Cách lấy kiến trúc trình biên dịch trong Android.mk động
- 13. Liên kết C thư viện tĩnh đã biên dịch với Chương trình C++
- 14. Biên dịch C++ với Cygwin
- 15. Có thể sử dụng tăng tốc GPU khi biên dịch nhiều chương trình trên trình biên dịch gcc không?
- 16. Cơ sở hạ tầng trình biên dịch LLVM cho các kiến trúc VLIW
- 17. Trình biên dịch không được hỗ trợ 'GCC 4.2' được chọn cho kiến trúc 'i386'
- 18. Có thể thiết lập trình biên dịch chéo gcc trên Linux để biên dịch các mục tiêu 64 bit trên kiến trúc 32 bit không?
- 19. Không thể biên dịch C++ với gcc
- 20. Xây dựng Boost với trình biên dịch LSB C++
- 21. Đề xuất kiến trúc hướng dịch vụ
- 22. C# "==" điều hành: trình biên dịch hành vi với cấu trúc khác nhau
- 23. Không thể biên dịch chương trình C++ đơn giản trong Ubuntu
- 24. Khởi tạo bộ nhớ cụ thể cho bộ biên dịch
- 25. Xây dựng kiến không hoạt động: không thể tìm thấy trình biên dịch javac
- 26. bị lỗi '\' trong lỗi chương trình khi biên dịch
- 27. Ký hiệu không xác định cho kiến trúc x86_64: Tôi nên sử dụng kiến trúc nào?
- 28. C để trình biên dịch brainfuck?
- 29. Biên dịch và tối ưu hóa cho các kiến trúc đích khác nhau
- 30. Tính năng thư viện C++ 11 phụ thuộc vào trình biên dịch cụ thể proxys