kết hợp hai tệp đối tượng .o đã được biên dịch GCC thành tệp .o thứ ba


84

Làm cách nào để kết hợp hai tệp đối tượng .o đã được GCC biên dịch thành tệp .o thứ ba?

$ gcc -c  a.c -o a.o
$ gcc -c  b.c -o b.o
$ ??? a.o b.o -o c.o
$ gcc c.o other.o -o executable

Nếu bạn có quyền truy cập vào các tệp nguồn, -combinecờ GCC sẽ hợp nhất các tệp nguồn trước khi biên dịch:

$ gcc -c -combine a.c b.c -o c.o

Tuy nhiên, điều này chỉ hoạt động đối với các tệp nguồn và GCC không chấp nhận .otệp làm đầu vào cho lệnh này.

Thông thường, liên kết .ocác tệp không hoạt động bình thường, vì bạn không thể sử dụng đầu ra của trình liên kết làm đầu vào cho nó. Kết quả là một thư viện được chia sẻ và không được liên kết tĩnh vào tệp thực thi kết quả.

$ gcc -shared a.o b.o -o c.o
$ gcc c.o other.o -o executable
$ ./executable
./executable: error while loading shared libraries: c.o: cannot open shared object file: No such file or directory
$ file c.o
c.o: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
$ file a.o
a.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped

1
gcc hiện không có -combinetùy chọn. Nó tồn tại trong gcc 4.1.2 và không tồn tại trong gcc 6.3.0 (người khác có thể tìm ra ngay khi nó bị xóa).
Keith Thompson

Câu trả lời:


98

Chuyển -relocatablehoặc -rđến ldsẽ tạo một đối tượng phù hợp làm đầu vào của ld.

$ ld -relocatable a.o b.o -o c.o
$ gcc c.o other.o -o executable
$ ./executable

Tệp được tạo có cùng loại với .otệp gốc .

$ file a.o
a.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
$ file c.o
c.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped

2
Có thể thực hiện phép toán nghịch đảo không? tức là sản xuất ao và bo từ co?
Bert Regelink

7
@BertRegelink không, bởi vì không có nghịch đảo duy nhất, Về mặt toán học, không phải là nhóm hình thức: P
Alec Teal

7
Cảnh báo: --relocatablecó vẻ ít di động hơn. Các ld đi kèm với Android NDK chỉ nhận dạng được -relocatable. Nếu bạn cần tính di động, hãy sử dụng -r.
Martin Bonner ủng hộ Monica

3
@matthijs Từ cũng vậy; sự khác biệt là một hoặc hai trừ.
Martin Bonner ủng hộ Monica,

1
À, không thấy. Vì vậy, NDK của Android chỉ nhận dạng được -relocatable -r nhưng không --relocatable. Cảm ơn đã làm rõ!
Matthijs Kooijman

10

Nếu bạn muốn tạo một kho lưu trữ gồm hai hoặc nhiều tệp .o (tức là một thư viện tĩnh), hãy sử dụng arlệnh:

ar rvs mylib.a file1.o file2.o

@Lucian Nhưng tại sao bạn muốn làm điều này? Thư viện tĩnh thuận tiện hơn nhiều để liên kết với tệp .o.

5
Tôi cần chạy objcopytrên tệp kết quả và tạo một số loại ký hiệu cục bộ cho tệp để chúng không hiển thị bên ngoài. Một số ký hiệu cần được bản địa hóa được tham chiếu giữa tệp a.ob.o. Tôi không thể bản địa hóa các tệp riêng lẻ - vì các ký hiệu sẽ không được tìm thấy tại thời điểm trình liên kết - và tôi cũng không thể bản địa hóa các ký hiệu từ kho lưu trữ tĩnh.
Lucian Adrian Grijincu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.