GNUツールチェーンを使用してプロジェクトをビルドしています。リンクを取得するまですべてが正常に機能します。リンカーがcrti.o
がない/見つからないというメッセージを表示します。これは私のオブジェクトファイルの1つではありません。libcに関連しているようですが、なぜcrti.o
が必要になるのか理解できません。たとえば、libc.a
などのライブラリファイルを使用しないのでしょうか。
Armプラットフォーム用にクロスコンパイルしています。ツールチェーンにファイルがありますが、リンカーにそれを含めるにはどうすればよいですか?
crti.o
は「ライブラリ」検索パスの1つにありますが、ライブラリパスで.o
ファイルを探す必要がありますか?
gcc
とld
の検索パスは同じですか?
_crti.o
_はbootstrapライブラリで、通常は非常に小さいです。通常は静的にバイナリにリンクされています。これは_/usr/lib
_にあります。
バイナリディストリビューションを実行している場合、コンパイルされたプログラムを実行する必要はなく、ビルドするだけでよいため、開発者向けのすべてのものを-devパッケージ(libc6-devなど)に入れる傾向があります。
あなたはクロスコンパイルしていませんか?
クロスコンパイルしている場合、通常はgccの検索パスがcrti.oの場所と一致しないことが問題です。ツールチェーンの作成時に作成されているはずです。最初に確認するのは_gcc -print-search-dirs
_であり、crti.oがこれらのパスのいずれかにあるかどうかを確認します。
リンクは実際にはldによって行われますが、gccによってパスが渡されます。おそらく、何が起こっているのかを見つける最も速い方法は、helloworld.cプログラムをコンパイルし、それをトレースして、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 ENOENT
への多数の試みが見られる場合、ld
は混乱しており、それが開いているパスがどこから来たかを確認したい...
クロスコンパイル中に同じ問題が発生しました。 crti.oは<sysroot>/usr/lib64にありましたが、リンカはそれを見つけませんでした。
空のディレクトリを作成すると判明<sysroot>/usr/lib問題が修正されました。リンカは最初にパス<sysroot>/usr/libを検索し、存在する場合にのみ<sysroot>/usr/lib64を検討するようです。
これはリンカのバグですか?または、この動作はどこかに文書化されていますか?
私の場合 Linux Mint 18.0/Ubuntu 16.04
、 私は全くない crti.o
まったく:
$ find /usr/ -name crti*
何も見つからないので、開発者パッケージをインストールします。
Sudo apt-get install libc6-dev
いくつかのライブラリを見つけた場合 こちらをお読みください
クロスコンパイラの設定が不適切な場合にも、同様の問題が発生しました。私はそれのようにそれを回避しました:
/home/rob/compiler/usr/bin/arm-linux-gcc --sysroot=/home/rob/compiler hello.c
これは、/ lib、/ usr/includeなどがsysrootオプションで指定された場所に存在することを前提としています。これはおそらく、想定されている方法とは異なりますが、単純なCファイルをコンパイルする必要があるときに問題が発生しました。
OK私はツールチェーンを再インストールする必要があったので、不足しているファイルが含まれていました。 gccパス上で見つけたはずなので、奇妙に思えます。私が推測する主な問題は、自分のコンピューターに15個ほどのcrti.oファイルがあり、正しいファイルを指していなかったことです。それでもまだ作れませんが、今は機能します:-)助けてくれてありがとう:-)
デフォルトのUbuntu 8.04インストールでも同じ種類の問題が発生します。 libc開発者のヘッダー/ファイルを手動で取得して機能させる必要がありました。
これは私のために解決されました(ARM用のpjsipをクロスコンパイル):
export LDFLAGS='--sysroot=/home/me/<path-to-my-sysroot-parent>/sysroot'