我一直在试图理解我得到的关于 _sbrk 函数的链接错误,并在库中偶然发现了这个函数定义。
extern caddr_t _sbrk(int incr);
// ... some other definitions ...
extern caddr_t _sbrk(int incr)
{
static unsigned char *heap = NULL;
unsigned char *prev_heap;
if (heap == NULL) {
heap = (unsigned char *)&_end;
}
prev_heap = heap;
heap += incr;
return (caddr_t) prev_heap;
}
现在,我知道extern
函数声明中的作用,但在函数定义中使用时我不知道它的含义......
有谁知道这样extern
使用有什么意义?
有问题的文件位于asf/sam/utils/syscalls/gcc/syscalls.c
目录中的 Atmel 软件框架 (ASF) 中。
它在嵌入式环境中,我收到一堆与缺少_exit
, _kill
, _sbrk
...的定义有关的 linkrt 错误
生成存根是有意义的,但我希望至少_sbrk
给出的定义会起作用?
更新:
好的,所以添加一些关于我如何将所有这些链接在一起的信息似乎可能会有所帮助。
我有一个可执行项目(使用 GCC 构建),我有一个链接到生成的可执行文件(也使用 GCC 构建)的静态库项目。
它们都没有启用优化(它可以更容易地在嵌入式目标上进行调试,而不会像在药物上那样跳跃)。
静态库包括上面提到的 ASF 代码。ASF 由 Atmel Studio 6.0 中包含的某个向导自动生成。
静态库中的一些代码包括<stdio.h>
我的目的不需要的代码,但我真的不想更改自动生成的代码(它必然会撤消我的更改)。
来自链接器的错误如下:
Invoking: ARM/GNU Linker : (crosstool-NG 1.15.3 - Atmel build: 59) 4.7.0
"C:\Program Files (x86)\Atmel\Atmel Studio
6.0\extensions\Atmel\ARMGCC\3.3.1.128\ARMGCCToolchain\bin\arm-none-eabi-gcc.exe" -o
Bootloader_Stage1.elf cmsis/src/startup_sam3n.o cmsis/src/system_sam3n.o
Bootloader_Stage1.o -Wl,-Map="Bootloader_Stage1.map" -Wl,--start-group -lm -
lBootloaderShared -Wl,--end-group -L"../cmsis/linkerScripts" -
L"../../BootloaderShared/Debug" -Wl,--gc-sections -Tsam3n4b_flash.ld -mcpu=cortex-m3
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-abort.o): In function
`abort':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/stdlib/abort.c(63,1): undefined reference to `_exit'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-sbrkr.o): In function
`_sbrk_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/sbrkr.c(60,1): undefined reference to `_sbrk'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-signalr.o): In function
`_kill_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/signalr.c(61,1): undefined reference to `_kill'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-signalr.o): In function
`_getpid_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/signalr.c(96,1): undefined reference to `_getpid'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-writer.o): In function
`_write_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/writer.c(58,1): undefined reference to `_write'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-closer.o): In function
`_close_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/closer.c(53,1): undefined reference to `_close'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-fstatr.o): In function
`_fstat_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/fstatr.c(62,1): undefined reference to `_fstat'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-isattyr.o): In function
`_isatty_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/isattyr.c(58,1): undefined reference to `_isatty'
Invoking: ARM/GNU Linker : (crosstool-NG 1.15.3 - Atmel build: 59) 4.7.0
"C:\Program Files (x86)\Atmel\Atmel Studio
6.0\extensions\Atmel\ARMGCC\3.3.1.128\ARMGCCToolchain\bin\arm-none-eabi-gcc.exe" -o
Bootloader_Stage1.elf cmsis/src/startup_sam3n.o cmsis/src/system_sam3n.o
Bootloader_Stage1.o -Wl,-Map="Bootloader_Stage1.map" -Wl,--start-group -lm -
lBootloaderShared -Wl,--end-group -L"../cmsis/linkerScripts" -
L"../../BootloaderShared/Debug" -Wl,--gc-sections -Tsam3n4b_flash.ld -mcpu=cortex-m3
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-abort.o): In function
`abort':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/stdlib/abort.c(63,1): undefined reference to `_exit'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-sbrkr.o): In function
`_sbrk_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/sbrkr.c(60,1): undefined reference to `_sbrk'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-signalr.o): In function
`_kill_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/signalr.c(61,1): undefined reference to `_kill'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-signalr.o): In function
`_getpid_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/signalr.c(96,1): undefined reference to `_getpid'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-writer.o): In function
`_write_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/writer.c(58,1): undefined reference to `_write'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-closer.o): In function
`_close_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/closer.c(53,1): undefined reference to `_close'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-fstatr.o): In function
`_fstat_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/fstatr.c(62,1): undefined reference to `_fstat'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-isattyr.o): In function
`_isatty_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/isattyr.c(58,1): undefined reference to `_isatty'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-lseekr.o): In function
`_lseek_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/lseekr.c(58,1): undefined reference to `_lseek'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-readr.o): In function
`_read_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/readr.c(58,1): undefined reference to `_read'
collect2.exe(0,0): ld returned 1 exit statusc:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-lseekr.o): In function
`_lseek_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/lseekr.c(58,1): undefined reference to `_lseek'
c:/program files (x86)/atmel/atmel studio
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none-
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-readr.o): In function
`_read_r':
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib-
1.19.0/newlib/libc/reent/readr.c(58,1): undefined reference to `_read'
collect2.exe(0,0): ld returned 1 exit status
更新 2:
我已经解决了我的链接问题。似乎 Atmel 软件框架包括#include <assert.h>
调用所有其他函数的那个。在该标题中,assert()
宏定义如下
#ifdef NDEBUG /* required by ANSI standard */
# define assert(__e) ((void)0)
#else
# define assert(__e) ((__e) ? (void)0 : __assert_func (__FILE__, __LINE__, \
__ASSERT_FUNC, #__e))
定义 NDEBUG 后,链接问题就消失了。据我所见NDEBUG
,没有在其他任何地方使用(不删除我依赖的任何其他代码),所以我可以保留定义的符号。
正如我之前提到的,我已经接受了回答问题的答案extern
并投票给了有助于解决链接问题的答案。