At this point you have an executable.
Không. Tại thời điểm này, bạn có tệp đối tượng không tự thực thi được.
But if you actually run that executable what happens?
Something như thế này:
h2co3-macbook:~ h2co3$ clang -Wall -o quirk.o quirk.c -c
h2co3-macbook:~ h2co3$ chmod +x quirk.o
h2co3-macbook:~ h2co3$ ./quirk.o
-bash: ./quirk.o: Malformed Mach-o file
tôi nói bạn nó không phải là một thực thi.
Is the problem that you may have included *.h files, and those only contain function prototypes?
Khá gần, thực sự. Một đơn vị dịch (tập tin .c) (thường) được chuyển thành mã lắp ráp/máy đại diện cho những gì nó làm. Nếu nó gọi một hàm, thì sẽ có một tham chiếu đến hàm đó trong tệp, nhưng không có định nghĩa.
So if you actually call one of the functions from those files, it won't have a definition and your program will crash?
Như tôi đã nói, nó thậm chí sẽ không chạy. Hãy để tôi lặp lại: một tệp đối tượng là không thể thực thi được.
what exactly does linking do, under the hood? How does it find the .c file associated with the .h that you included [...]
Không. Nó tìm kiếm các tệp đối tượng khác được tạo từ các tệp .c và cuối cùng là các thư viện (về cơ bản chỉ là các tập hợp các tệp đối tượng khác).
Và nó tìm thấy chúng bởi vì bạn nói với nó những gì cần tìm. Giả sử bạn có một dự án bao gồm hai file .c mà gọi chức năng của nhau, điều này sẽ không làm việc:
gcc -c file1.c -o file1.o
gcc -c file2.c -o file2.o
gcc -o my_prog file1.o
Nó sẽ thất bại với một lỗi mối liên kết: các mối liên kết sẽ không tìm thấy định nghĩa của các hàm được triển khai trong file2.c
(và file2.o
). Nhưng điều này sẽ làm việc: file
gcc -c file1.c -o file1.o
gcc -c file2.c -o file2.o
gcc -o my_prog file1.o file2.o
[...] and how does it inject that into your machine code?
Object chứa tài liệu tham khảo còn sơ khai (thường là dưới hình thức địa chỉ điểm vào chức năng hoặc rõ ràng, tên con người có thể đọc được) đến các chức năng mà họ gọi. Sau đó, trình liên kết xem xét từng thư viện và tệp đối tượng, tìm các tham chiếu (, phát ra lỗi nếu không tìm thấy định nghĩa hàm), sau đó thay thế các tham chiếu sơ khai bằng các hướng dẫn mã máy "thực sự gọi hàm này". (Vâng, đây phần lớn là đơn giản, nhưng nếu không có bạn hỏi về một kiến trúc cụ thể và một trình biên dịch cụ thể/mối liên kết, thật khó để nói chính xác hơn ...)
Is static when you actually recompile the source of the library for every executable you create?
số liên kết tĩnh có nghĩa là mã máy của các tệp đối tượng của thư viện thực sự được sao chép/hợp nhất vào tệp thực thi cuối cùng của bạn. Liên kết động có nghĩa là một thư viện được nạp vào bộ nhớ một lần, sau đó các tham chiếu hàm stub nói trên được giải quyết bởi hệ điều hành khi tệp thực thi của bạn được khởi chạy. Không có mã máy nào từ thư viện sẽ được sao chép vào tệp thực thi cuối cùng của bạn. (Vì vậy, ở đây, mối liên kết trong chuỗi công cụ chỉ thực hiện một phần công việc.)
Sau đây có thể giúp bạn đạt được giác ngộ: nếu bạn liên kết tĩnh một tệp thực thi, nó sẽ được khép kín. Nó sẽ chạy bất cứ nơi nào (trên một kiến trúc tương thích anyway). Nếu bạn liên kết nó động, nó sẽ chỉ chạy trên một máy nếu máy đó có tất cả các thư viện được cài đặt mà chương trình tham chiếu.
So you compile one executable library that is shared by all of your processes that use it? How is that possible, exactly? Wouldn't it be outside of the address space of the processes trying to access it?
Thành phần liên kết/bộ tải động của HĐH sẽ xử lý tất cả.
Also, for dynamic linking, don't you still need to compile the library at some juncture in time?
Như tôi đã đề cập: có, nó đã được biên soạn rồi. Sau đó, nó được tải tại một số điểm (thường là khi nó lần đầu tiên được sử dụng) vào bộ nhớ.
When is it compiled?
Một thời gian trước khi có thể sử dụng. Thông thường, một thư viện được biên dịch, sau đó cài đặt vào một vị trí trên hệ thống của bạn để hệ điều hành và trình biên dịch/liên kết biết về sự tồn tại của nó, sau đó bạn có thể bắt đầu biên dịch (um, liên kết) các chương trình sử dụng thư viện đó. Không sớm hơn.
có thể trùng lặp của [Cách liên kết C++ hoạt động trong thực tế?] (Http://stackoverflow.com/questions/12122446/how-does-c-linking-work-in-practice) –