C语言 使用 GCC 交叉编译器时对 printf 的未定义引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30012353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Undefined reference to printf when using GCC cross compiler
提问by pwaring
I'm trying to get the following simple 'Hello World' program to compile using a cross compiler (GCC 4.9.2) targeting mips:
我正在尝试使用交叉编译器(GCC 4.9.2)针对以下简单的“Hello World”程序进行编译mips:
#include <stdio.h>
int main()
{
int x = 5;
printf("x = %d\n", x);
}
The xvariable is there to stop GCC changing printfto puts, which it seems to do automatically for a simple newline-terminated string.
该x变量用于阻止 GCC 更改printf为puts,对于简单的以换行符结尾的字符串,它似乎会自动执行此操作。
I've built a cross compiler under ${HOME}/xcand am executing it using the following command:
我在下面构建了一个交叉编译器,${HOME}/xc并使用以下命令执行它:
${HOME}/xc/bin/mips-gcc -v hello.c
However, I'm getting the following error:
但是,我收到以下错误:
/tmp/ccW5mHJu.o: In function `main':
(.text+0x24): undefined reference to `printf'
collect2: error: ld returned 1 exit status
I'm assuming this is a problem with the linker, as I'd expect the process to fail earlier if for example stdio.hcouldn't be found on the search path. I can compile a simpler program which simply returns zero, so it's not the case that the entire toolchain is broken, presumably just the standard library linking (I'm using newlib 2.2.0-1).
我假设这是链接器的问题,因为如果例如stdio.h在搜索路径上找不到,我预计该过程会更早失败。我可以编译一个更简单的程序,它只返回零,所以并不是整个工具链都被破坏了,大概只是标准库链接(我使用的是 newlib 2.2.0-1)。
I get the same error regardless of whether I run the cross compiler under Linux (Ubuntu 14.10) or Cygwin (Windows 8).
无论我是在 Linux (Ubuntu 14.10) 还是 Cygwin (Windows 8) 下运行交叉编译器,我都会遇到同样的错误。
The full output from GCC is:
GCC 的完整输出是:
Using built-in specs.
COLLECT_GCC=/home/paul/xc/bin/mips-gcc
COLLECT_LTO_WRAPPER=/home/paul/xc/libexec/gcc/mips/4.9.2/lto-wrapper
Target: mips
Configured with: /home/paul/xc/mips/tmp/gcc-4.9.2/configure --prefix=/home/paul/xc --target=mips --enable-languages=c --with-newlib --without-isl --without-cloogs --disable-threads --disable-libssp --disable-libgomp --disable-libmudflap
Thread model: single
gcc version 4.9.2 (GCC)
COLLECT_GCC_OPTIONS='-v'
/home/paul/xc/libexec/gcc/mips/4.9.2/cc1 -quiet -v hello.c -quiet -dumpbase hello.c -auxbase hello -version -o /tmp/ccCpAajQ.s
GNU C (GCC) version 4.9.2 (mips)
compiled by GNU C version 4.9.1, GMP version 6.0.0, MPFR version 3.1.2, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/sys-include"
#include "..." search starts here:
#include <...> search starts here:
/home/paul/xc/lib/gcc/mips/4.9.2/include
/home/paul/xc/lib/gcc/mips/4.9.2/include-fixed
/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/include
End of search list.
GNU C (GCC) version 4.9.2 (mips)
compiled by GNU C version 4.9.1, GMP version 6.0.0, MPFR version 3.1.2, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: cffaaedf0b24662e67a5d97387fc5b17
COLLECT_GCC_OPTIONS='-v'
/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/bin/as -EB -O1 -no-mdebug -mabi=32 -o /tmp/ccW5mHJu.o /tmp/ccCpAajQ.s
COMPILER_PATH=/home/paul/xc/libexec/gcc/mips/4.9.2/:/home/paul/xc/libexec/gcc/mips/4.9.2/:/home/paul/xc/libexec/gcc/mips/:/home/paul/xc/lib/gcc/mips/4.9.2/:/home/paul/xc/lib/gcc/mips/:/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/bin/
LIBRARY_PATH=/home/paul/xc/lib/gcc/mips/4.9.2/:/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/lib/
COLLECT_GCC_OPTIONS='-v'
/home/paul/xc/libexec/gcc/mips/4.9.2/collect2 -plugin /home/paul/xc/libexec/gcc/mips/4.9.2/liblto_plugin.so -plugin-opt=/home/paul/xc/libexec/gcc/mips/4.9.2/lto-wrapper -plugin-opt=-fresolution=/tmp/cc8TAJb9.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc -EB /home/paul/xc/lib/gcc/mips/4.9.2/crti.o /home/paul/xc/lib/gcc/mips/4.9.2/crtbegin.o -L/home/paul/xc/lib/gcc/mips/4.9.2 -L/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/lib /tmp/ccW5mHJu.o -lgcc -lgcc /home/paul/xc/lib/gcc/mips/4.9.2/crtend.o /home/paul/xc/lib/gcc/mips/4.9.2/crtn.o
/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000400050
/tmp/ccW5mHJu.o: In function `main':
(.text+0x24): undefined reference to `printf'
collect2: error: ld returned 1 exit status
The build script I'm using is here (I wrote it based on half a dozen tutorials which all suggested slightly different things):
我正在使用的构建脚本在这里(我是根据六个教程编写的,这些教程都提出了略有不同的内容):
https://github.com/UoMCS/mips-cross-compile
https://github.com/UoMCS/mips-cross-compile
Basically it does the following steps:
基本上它执行以下步骤:
- Build binutils.
- Build GCC (stage 1).
- Build newlib.
- Build GCC (stage 2).
- 构建 binutils。
- 构建 GCC(阶段 1)。
- 构建新库。
- 构建 GCC(第 2 阶段)。
I'm aware that there are other tools such as crosstool-ng and builtroot, however the person I'm building this toolchain for wants to edit parts of binutils before setting off the build process, and the toolchain also has to work under Cygwin (crosstool-ng won't for various reasons, including case-sensitive file paths).
我知道还有其他工具,例如 crosstool-ng 和 builtroot,但是我正在为其构建此工具链的人想要在开始构建过程之前编辑 binutils 的一部分,并且工具链也必须在 Cygwin 下工作( crosstool-ng 不会出于各种原因,包括区分大小写的文件路径)。
I think this is probably going to be something obvious, but I've been messing around with this for a week and can't see what it could be. Any help would be greatly appreciated!
我认为这可能是显而易见的事情,但我已经搞了一个星期,看不出它会是什么。任何帮助将不胜感激!
采纳答案by Peter
It is necessary to build libraries to go with your cross compiler. In particular, you need to have a cross-compiled version of glibc or some other implementation of the standard library, to get a version of printf().
有必要构建库以配合您的交叉编译器。特别是,您需要有 glibc 的交叉编译版本或标准库的其他一些实现,才能获得printf().
Have a look at this linkfor an example of the type of things you need to consider to get all the things you need - the cross-compiler, the headers, and libraries.
请查看此链接,以获取获得所需的所有内容所需考虑的事物类型的示例 - 交叉编译器、头文件和库。
回答by 4566976
A custom specs file could work:
自定义规格文件可以工作:
cd /home/paul/xc/lib/gcc/mips/4.9.2/
${HOME}/xc/bin/mips-gcc -dumpspecs > specs
Add to the specs file:
添加到规格文件:
*lib:
-lc
Note that there must be empty lines before *lib:and after -lc. Perhaps you have to change the library name to the name of your newlib-c-library. Perhaps more must be added than only -lc, e.g. the *lib:-section on my Linux looks more complex.
需要注意的是必须有前空行*lib:和之后-lc。也许您必须将库名称更改为您的 newlib-c-library 的名称。也许必须添加的不仅仅是-lc,例如*lib:我的 Linux 上的-section 看起来更复杂。
UPDATE更新:
liblib默认库的内置规范在此处配置:In file gcc-4.9.2/gcc/gcc.clines 527-530:
在文件gcc-4.9.2/gcc/gcc.c行 527-530 中:
/* config.h can define LIB_SPEC to override the default libraries. */
#ifndef LIB_SPEC
#define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
#endif
In file gcc-4.9.2/gcc/config/mips/elf.hlines 40-42:
在文件gcc-4.9.2/gcc/config/mips/elf.h第 40-42 行中:
/* Leave the linker script to choose the appropriate libraries. */
#undef LIB_SPEC
#define LIB_SPEC ""
Perhaps the default LIB_SPECin gcc.cworks for you by commenting out lines 40-42 in elf.h.
Perhaps you need to edit elf.hand replace the empty LIB_SPECwith "-lc"or something similar.
也许默认LIB_SPEC在gcc.c您的作品通过注释掉线40-42 elf.h。也许您需要编辑elf.h和替换空LIB_SPEC的"-lc"或类似的东西。
UPDATE更新:当你配置
gccgcc你给--target=mips--target=mips. 在gcc-4.9.2\gcc\config.gccgcc-4.9.2\gcc\config.gcc有其他MIPS-个目标,这是更具体的,例如mips*-*-linux*mips*-*-linux*,可能选择一个合适的给出正确的LIB_SPECLIB_SPEC和连接一定会成功。UPDATE更新:大端 Linux 目标:
mips-unknown-linux-gnumips-unknown-linux-gnu小端 Linux 目标:mipsel-unknown-linux-gnumipsel-unknown-linux-gnusource来源UPDATE更新:使用您的构建脚本,我能够通过以下修改链接您的示例程序:
In your config.sh:
在您的config.sh:
export ISL_VERSION="0.12.2"
In file gcc-4.9.2/gcc/config/mips/elf.hlines 40-42:
在文件gcc-4.9.2/gcc/config/mips/elf.h第 40-42 行中:
/* Leave the linker script to choose the appropriate libraries. */
#undef LIB_SPEC
#define LIB_SPEC "-lc -lcfe -lc"
If you don't want the modification in elf.hthe libraries must be given when invoking mips-gcc.
如果您不想在elf.h库中进行修改,则必须在调用mips-gcc.
UPDATE更新:
newlib doesn't work at all, GCC fails in the second stage with an error about not being able to find crti.o etc.
newlib 根本不起作用,GCC 在第二阶段失败,出现关于无法找到 crti.o 等的错误。
Strange, using your build script crti.owas created:
奇怪的是,使用您的构建脚本crti.o创建了:
[osboxes@osboxes 4.9.2]$ pwd
/home/osboxes/xc/lib/gcc/mips/4.9.2
[osboxes@osboxes 4.9.2]$ ll
total 6240
-rw-r--r--. 1 osboxes osboxes 3248 May 16 19:49 crtbegin.o
-rw-r--r--. 1 osboxes osboxes 1924 May 16 19:49 crtend.o
-rw-r--r--. 1 osboxes osboxes 1040 May 16 19:49 crti.o
-rw-r--r--. 1 osboxes osboxes 1056 May 16 19:49 crtn.o
drwxrwxr-x. 3 osboxes osboxes 4096 May 16 19:49 include
drwxrwxr-x. 2 osboxes osboxes 4096 May 16 19:45 include-fixed
drwxrwxr-x. 3 osboxes osboxes 4096 May 16 19:49 install-tools
-rw-r--r--. 1 osboxes osboxes 6289352 May 16 19:49 libgcc.a
-rw-r--r--. 1 osboxes osboxes 56844 May 16 19:49 libgcov.a
drwxrwxr-x. 3 osboxes osboxes 4096 May 16 19:49 plugin
-rw-rw-r--. 1 osboxes osboxes 6215 May 18 18:45 specs
回答by paxmemento
Try linking the library on the command line:
尝试在命令行上链接库:
${HOME}/xc/bin/mips-gcc -v hello.c -lib
Including the std libraries (lib and io)header links the implementations by default (libc.so or .a). However, you are using a 'user-defined' implementation and may not be linking the proper one.
包括 std 库(lib 和 io)标头默认链接实现(libc.so 或 .a)。但是,您使用的是“用户定义”的实现并且可能没有链接正确的实现。
I suggest explicit linkage on the command line. I'm not certain of the syntax.
我建议在命令行上进行显式链接。我不确定语法。
EDIT: Or better Still, use a makefile to compile with the following lines, and specifying other include directories in the INCLUDES place holder:
编辑:或者更好的是,使用 makefile 编译以下行,并在 INCLUDES 占位符中指定其他包含目录:
CC = gcc
CXX = g++
INCLUDES =
CFLAGS = -g -Wall $(INCLUDES)
CXXFLAGS = -g -Wall $(INCLUDES)
LDFLAGS = -g
hello: hello.o newlib.o
hello.o: hello.c newlib.h
newlib.o: newlib.c newlib.h
newlib.his the header file you'll include in newlib.c(implementation/definition) source file (that declares the functions) and hello.c. It may be named differently from stdio.h.
newlib.h是您将包含在newlib.c(实现/定义)源文件(声明函数)中的头文件和hello.c. 它的名称可能与stdio.h.
Check this out, it may help:
看看这个,它可能有帮助:
Why do you have to link the math library in C?
and this too:
这也是:
回答by totten
回答by yurenchen
printf()was implemented in libc,
printf()实施于libc,
Please check your c lib, such as glibc, oh, yours is newlib.
请检查您的 c lib,例如glibc,哦,您的是newlib.
- try @4566976 's way
- use
readelf -scheck is there aprintfsection exists inlibc.solibc.a
- 试试@4566976 的方式
- 使用
readelf -s检查是否存在一个printf部分libc.solibc.a
( i'm not sure the lib filename in newlib, mine is glibc )
(我不确定 newlib 中的 lib 文件名,我的是 glibc )

![C语言 生成范围 [min,max] 内的随机数](/res/img/loading.gif)