web-dev-qa-db-ja.com

GCCクロスコンパイラを使用する場合のprintfへの未定義の参照

mipsをターゲットとするクロスコンパイラ(GCC 4.9.2)を使用してコンパイルする次の簡単な「Hello World」プログラムを取得しようとしています。

#include <stdio.h>

int main()
{
  int x = 5;
  printf("x = %d\n", x);
}

x変数は、GCCがprintfputsに変更するのを止めるためにあります。これは、単純な改行で終わる文字列に対して自動的に行われるようです。

${HOME}/xcの下にクロスコンパイラを構築し、次のコマンドを使用して実行しています。

${HOME}/xc/bin/mips-gcc -v hello.c

ただし、次のエラーが表示されます。

/tmp/ccW5mHJu.o: In function `main':
(.text+0x24): undefined reference to `printf'
collect2: error: ld returned 1 exit status

たとえばstdio.hが検索パスで見つからなかった場合、プロセスが以前に失敗することが予想されるため、これはリンカーの問題であると想定しています。単純にゼロを返す単純なプログラムをコンパイルできるので、ツールチェーン全体が壊れているわけではなく、おそらく標準ライブラリのリンクだけです(newlib 2.2.0-1を使用しています)。

Linux(Ubuntu 14.10)またはCygwin(Windows 8)のどちらでクロスコンパイラを実行しても、同じエラーが発生します。

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

私が使用しているビルドスクリプトはここにあります(私はすべてがわずかに異なることを示唆した6ダースのチュートリアルに基づいてそれを書きました):

https://github.com/UoMCS/mips-cross-compile

基本的に、次の手順を実行します。

  1. Binutilsをビルドします。
  2. GCCをビルドします(ステージ1)。
  3. Newlibをビルドします。
  4. GCCをビルドします(ステージ2)。

Crosstool-ngやbuiltrootなどの他のツールがあることは承知していますが、このツールチェーンを構築している人は、ビルドプロセスを開始する前にbinutilsの一部を編集したいので、Cygwin( crosstool-ngは、大文字と小文字を区別するファイルパスなど、さまざまな理由によります。

これはおそらく明白なことになると思いますが、私はこれを1週間いじっており、それが何であるかを見ることができません。どんな助けも大歓迎です!

13
pwaring

クロスコンパイラに対応するには、ライブラリを構築する必要があります。特に、printf()のバージョンを取得するには、glibcのクロスコンパイルバージョンまたは標準ライブラリのその他の実装が必要です。

このリンク を見て、必要なものすべてを取得するために考慮しなければならないもののタイプの例-クロスコンパイラー、ヘッダー、およびライブラリーを参照してください。

5
Peter

コマンドラインでライブラリをリンクしてみてください:

${HOME}/xc/bin/mips-gcc -v hello.c -lib

Stdライブラリ(libおよびio)ヘッダーを含めると、デフォルトで実装がリンクされます(libc.soまたは.a)。ただし、「ユーザー定義」実装を使用しており、適切な実装をリンクしていない可能性があります。

コマンドラインで明示的なリンケージをお勧めします。構文がわかりません。

編集:またはそれでも、メイクファイルを使用して次の行でコンパイルし、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.hは、newlib.c(実装/定義)ソースファイル(関数を宣言する)およびhello.cに含めるヘッダーファイルです。 stdio.hとは異なる名前が付けられている場合があります。

これを確認してください、それは役立つかもしれません:

なぜCで数学ライブラリをリンクする必要があるのですか?

これも:

http://www.tldp.org/HOWTO/Glibc2-HOWTO-6.html

0
paxmemento

これを実現する最も便利な方法は、printfの代わりに putchar を使用することです。コードの一部を変更したり、printfのように実行されるマクロ/関数を追加する必要があるかもしれません。

0
totten