2012-03-26 34 views
5

Tôi đang làm việc trên phần mềm nhúng cho vi điều khiển ARM (SAM7) và sử dụng chuỗi công cụ Yagarto.Làm cách nào để buộc gcc sử dụng các triển khai tùy chỉnh của các hàm được triển khai newlibc?

Mã của tôi hiện liên kết libc.a. Tuy nhiên, tôi muốn sử dụng triển khai tùy chỉnh hàm dựng sẵn memcpy mà mã của tôi đã có.

Tôi đã cố gắng sử dụng -fno-BUILTIN và/hoặc -fno-BUILTIN-memcpy như quy định trong GCC Manual nhưng mối liên kết vẫn còn than phiền sẽ cảnh báo sau đây:

contiki-crazy-horse.a(flashd_efc.o): In function `memcpy': 
C:\Users\Melvin\GitRepo\projects\Amatis_Project\SAM7_Contiki\examples\er-rest-example/../../cpu/arm//at91sam7s-x/./flashd_efc.c:669: multiple definition of `memcpy' 
c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-memcpy.o):C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\string/../../../../../newlib-1.19.0/newlib/libc/string/memcpy.c:78: first defined here 
collect2: ld returned 1 exit status 
make: *** [rest-server-example-nosyms.crazy-horse] Error 1 
../../cpu/arm/at91sam7s-x/Makefile.at91sam7s-x:181: recipe for target `rest-server-example-nosyms.crazy-horse' failed 

cách chính xác là gì sử dụng triển khai tùy chỉnh của một số chức năng tích hợp gcc nhất định?

Chỉnh sửa 1: Thêm lệnh liên kết mà tôi đang sử dụng. Trong đoạn mã dưới đây Porject.a là một tệp lưu trữ được tạo với tất cả các tệp đối tượng của dự án.

CC  = arm-none-eabi-gcc 
CFLAGSNO = -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) -I$(CONTIKI_CPU)/loader \ 
     -I$(CONTIKI_CPU)/dbg-io \ 
      -I$(CONTIKI)/platform/$(TARGET) \ 
      ${addprefix -I,$(APPDIRS)} \ 
      -DWITH_UIP -DWITH_ASCII -DMCK=$(MCK) \ 
      -Wall $(ARCH_FLAGS) -g -D SUBTARGET=$(SUBTARGET) 

CFLAGS += $(CFLAGSNO) -O -DRUN_AS_SYSTEM -DROM_RUN -ffunction-sections 

LDFLAGS += -L $(CONTIKI_CPU) --verbose -T $(LINKERSCRIPT) -nostartfiles -Wl,-Map,$(TARGET).map 

$(CC) $(LDFLAGS) $(CFLAGS) -nostartfiles -o project.elf -lc Project.a 
+0

Cũng bao gồm dòng lệnh trình liên kết đã tạo lỗi này. – Clifford

+0

@Clifford Tôi đã chỉnh sửa bài đăng gốc để thêm thông tin bạn yêu cầu – maguirre

Trả lời

3

Nếu nó được tìm memcpy() trong libc.a, sau đó nó không phải là mâu thuẫn với bất kỳ "built-in", mà là với việc thực hiện newlib. Bạn cũng có thể cần phải chỉ định tùy chọn -nostdlibs và liên kết rõ ràng libc.a và libm.a khi cần thiết.

Tệp đối tượng (.o) được liên kết trước khi tệp lưu trữ thư viện (.a) được tìm kiếm, vì vậy nếu biểu tượng được giải quyết bởi tệp đối tượng, tệp sẽ không được tìm kiếm trong lưu trữ. Nếu bạn đặt các ghi đè của mình trong thư viện liên kết tĩnh, thì bạn chỉ cần liệt kê nó trước thư viện chuẩn (hoặc bất kỳ thư viện nào khác sử dụng thư viện chuẩn) trên dòng lệnh trình liên kết.

[Added]Sau đây ban đầu là một "bình luận" nhưng có lẽ phải ở trong câu trả lời; câu trả lời là "Chỉnh sửa 1" trong câu hỏi và nhận xét bên dưới về thứ tự liên kết:

Thay đổi -nostartfiles -o project.elf -lc Project.a thành -nostdlib -o project.elf -start-group Project.a -lc -end-group. Công tắc -nostdlib tắt liên kết mặc định của cả hai tệp khởi động (ví dụ: -nostartfiles) và thư viện chuẩn. Nhóm thư viện làm cho các thư viện trong nhóm được tìm kiếm lặp lại cho đến khi không có biểu tượng nào khác có thể được giải quyết, cho phép các phụ thuộc không theo thứ tự và vòng tròn như của bạn được giải quyết. Một hình thức thay thế cho các công tắc nhóm là -(Project.a -lc -).

+0

@Cliford. Lỗi của tôi. Bạn đang phải Có cách nào để chọn thực hiện memcpy tôi muốn mã của tôi để liên kết? Tôi không thể chuyển đổi thứ tự liên kết giữa Project.a và libc.a vì dự án của tôi có một số hàm sơ khai mà libc.a cần – maguirre

+2

@Mischief: Hoặc, tách các thư mục newlib của bạn khỏi các tệp dự án của bạn 'Project.a -lc stubs .a'. Sử dụng một kho lưu trữ cho các tập tin dự án của bạn là một điều bất thường để làm; bạn có thể tránh được vấn đề hoàn toàn bằng cách liên kết các tệp đối tượng trực tiếp như là tiêu chuẩn. Mã trong các tệp đối tượng sẽ luôn được sử dụng trong tùy chọn mã thư viện bất kể thứ tự liên kết; do đó, các phần tử libc sẽ được giải quyết bởi bất kỳ mã đối tượng nào mà bạn liên kết với các biểu tượng phù hợp, và bất kỳ mã đối tượng nào sẽ được giải quyết từ mã đối tượng khác trước mã thư viện, do đó memcpy() sẽ được ghi đè chính xác ngay cả đối với các cuộc gọi trong libc. – Clifford

+0

Tôi đồng ý với bạn về nhận xét của bạn về việc có mã trong kho lưu trữ là bất thường. Nếu/khi tôi có cách của tôi, nó sẽ được thay đổi – maguirre

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