28

私は GNU ツール チェーンを使用してプロジェクトを構築していますが、リンクするまではすべて正常に動作し、リンカはそれが見つからない/見つからないと文句を言いますcrti.o。これは私のオブジェクト ファイルの 1 つではなく、libc に関連しているようですが、なぜこれが必要なのか理解できませcrti.olibc.a

アームプラットフォーム用にクロスコンパイルしています。ツールチェーンにファイルがありますが、リンカーにそれを含めるにはどうすればよいですか?

crti.o「ライブラリ」検索パスの 1 つにあり.oますが、ライブラリ パスでファイルを検索する必要がありますか?

gccとの検索パスは同じldですか?

4

8 に答える 8

28

crti.oはブートストラップ ライブラリで、通常は非常に小さいです。通常、バイナリに静的にリンクされています。にあります/usr/lib

バイナリ ディストリビューションを実行している場合、コンパイルされたプログラムを実行する必要はなく、単にビルドするだけなので、すべての開発者用のものを -dev パッケージ (例: libc6-dev) に入れる傾向があります。

あなたはクロスコンパイルしていませんか?

クロスコンパイルしている場合、通常は gcc の検索パスが crti.o の場所と一致しないという問題があります。ツールチェーンがあったときに構築されているはずです。最初に確認することはgcc -print-search-dirs、crti.o がこれらのパスのいずれかにあるかどうかを確認することです。

リンクは実際にはldによって行われますが、そのパスはgccによって渡されます。おそらく、何が起こっているのかを知る最も簡単な方法は、helloworld.c プログラムをコンパイルし、それを strace して ld に何が渡されているかを確認し、何が起こっているかを確認することです。

strace -v -o log -f -e trace=open,fork,execve gcc hello.c -o test

ログ ファイルを開いて crti.o を検索すると、私の非クロス コンパイラが表示されます。

10616 execve("/usr/bin/ld", ["/usr/bin/ld", "--eh-frame-hdr", "-m", "elf_x86_64", "--hash-style=both", "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2", "-o"
, "test", "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "-L/usr/lib/gcc/x86_64-linux-g
nu/"..., "-L/usr/lib/gcc/x86_64-linux-gnu/"..., "-L/usr/lib/gcc/x86_64-linux-gnu/"..., "-L/lib/../lib", "-L/usr/lib/../lib", "-L/usr/lib/gcc/x86_64-linux-gnu
/"..., "/tmp/cc4rFJWD.o", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", "-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", "/usr/lib/gcc/x86_
64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."...],  "COLLECT_GCC=gcc", "COLLECT_GCC_OPTIONS=\'-o\' \'test\' "..., "COMPILER_PATH=/usr/lib/gcc/x86_6"..., "LIBRARY_PATH=/usr/lib/gcc/x86_64"..., "CO
LLECT_NO_DEMANGLE="]) = 0
10616 open("/etc/ld.so.cache", O_RDONLY) = 3
10616 open("/usr/lib/libbfd-2.18.0.20080103.so", O_RDONLY) = 3
10616 open("/lib/libc.so.6", O_RDONLY)  = 3
10616 open("test", O_RDWR|O_CREAT|O_TRUNC, 0666) = 3
10616 open("/usr/lib/gcc/x86_64-linux-gnu/4.2.3/../../../../lib/crt1.o", O_RDONLY) = 4
10616 open("/usr/lib/gcc/x86_64-linux-gnu/4.2.3/../../../../lib/crti.o", O_RDONLY) = 5
10616 open("/usr/lib/gcc/x86_64-linux-gnu/4.2.3/crtbegin.o", O_RDONLY) = 6
10616 open("/tmp/cc4rFJWD.o", O_RDONLY) = 7

への一連の試行が混乱しopen(...crti.o) = -1 ENOENTldいるのを見て、開いているパスがどこから来たのかを確認したい場合...

于 2008-09-18T10:54:09.183 に答える
6

クロスコンパイル中に同じ問題が発生しました。crti.o は<sysroot>/usr/lib64にありましたが、リンカーはそれを見つけられませんでした。

空のディレクトリ<sysroot>/usr/libを作成すると、問題が解決したことがわかりました。リンカーは最初にパス<sysroot>/usr/libを検索し、存在する場合にのみ<sysroot>/usr/lib64を考慮するようです。

これはリンカーのバグですか?または、この動作はどこかに文書化されていますか?

于 2015-05-08T06:52:14.940 に答える
1

セットアップが不十分なクロスコンパイラでも同様の問題がありました。私はそれを次のように回避しました:

/home/rob/compiler/usr/bin/arm-linux-gcc --sysroot=/home/rob/compiler hello.c

これは、sysroot オプションが指す場所に /lib、/usr/include などが存在することを前提としています。これはおそらく本来あるべき方法ではありませんが、単純な C ファイルをコンパイルする必要があるときに問題を解決してくれました。

于 2011-10-20T14:39:45.133 に答える
1

OK 不足しているファイルが含まれるように、ツール チェーンを再インストールする必要がありました。gcc パス上にあるはずだったので、奇妙に思えます。私が推測する主な問題は、コンピューターに 15 個ほどの異なる crti.o ファイルがあり、正しいファイルを指していなかったことです。それ以来、まだ作成されていませんが、現在は機能しています:-) 助けてくれてありがとう:-)

于 2008-09-18T14:41:26.843 に答える
1

クロスコンパイルする場合は、LDFLAGS に sysroot オプションを追加します。

export LDFLAGS=""--sysroot=${SDKTARGETSYSROOT}" -L${SDKTARGETSYSROOT}/lib -L${SDKTARGETSYSROOT}/usr/lib -L${SDKTARGETSYSROOT}/usr/lib/arm-poky-linux-gnueabi/5.3.0"
于 2019-12-09T08:03:37.400 に答える
0

デフォルトの Ubuntu 8.04 インストールでも同じ種類の問題が発生します。それを機能させるには、libc 開発者のヘッダー/ファイルを手動で取得する必要がありました。

于 2008-09-18T10:54:12.303 に答える
0

これで解決しました(ARM用のpjsipのクロスコンパイル):

export LDFLAGS='--sysroot=/home/me/<path-to-my-sysroot-parent>/sysroot'
于 2014-09-17T21:37:51.100 に答える