0

独自のライブラリのいくつかにリンクするアプリケーションがいくつかあります。最近、これらのライブラリにリンクする新しいアプリケーションを追加しましたが、これは Windows で正常にコンパイルされます。

ただし、Linux では、静的変数への「未定義の参照」エラーが表示されます。これはもちろん、変数が定義されていないことを意味します。エラーはライブラリで発生しますが、新しいアプリケーションにリンクされている場合のみです (既存のアプリケーションは引き続き正常にリンクされます)。

ご覧のとおり、コンパイラはそれkAppVersionが未定義であると言います。実際にVersion.cppで定義し、common をリンクした場合 ( CMakeLists.txtで指定)。target_link_libraries順番の関係かと思いましたがcommon、前base(エラーが発生した場所)に移動しても効果はないようです。さらに、他のCMakeLists.txt (例: シナジー用) では、このアプリケーションは正常にコンパイルされるため、順序は無関係に見えます。この同様の質問は、順序が重要であることを示唆しているように見えますが、私はこれで成功していません:

質問:ライブラリはリンクされていますが、参照は未定義です

私の唯一の考えは、 synergyd.cppまたはCDaemonApp.cppに何か問題がある可能性があるということです。

Scanning dependencies of target synergyd
[ 90%] Building CXX object src/cmd/synergyd/CMakeFiles/synergyd.dir/synergyd.o
Linking CXX executable ../../../../../bin/debug/synergyd
../../../../../lib/debug/libarch.a(CArch.o): In function `~XExitApp':
/srv/buildbot/synergy/1.4-linux32/build/src/lib/arch/../synergy/XSynergy.h:114: undefined reference to `vtable for XExitApp'
../../../../../lib/debug/libarch.a(CArch.o): In function `CArchAppUtil::exitApp(int)':
/srv/buildbot/synergy/1.4-linux32/build/src/lib/arch/CArchAppUtil.h:31: undefined reference to `XExitApp::XExitApp(int)'
/srv/buildbot/synergy/1.4-linux32/build/src/lib/arch/CArchAppUtil.h:31: undefined reference to `typeinfo for XExitApp'
../../../../../lib/debug/libarch.a(CArchAppUtilUnix.o): In function `CArchAppUtilUnix::parseArg(int const&, char const* const*, int&)':
/srv/buildbot/synergy/1.4-linux32/build/src/lib/arch/CArchAppUtilUnix.cpp:32: undefined reference to `CApp::isArg(int, int, char const* const*, char const*, char const*, int)'
/srv/buildbot/synergy/1.4-linux32/build/src/lib/arch/CArchAppUtilUnix.cpp:37: undefined reference to `CApp::isArg(int, int, char const* const*, char const*, char const*, int)'
../../../../../lib/debug/libbase.a(CLog.o): In function `CLog::insert(ILogOutputter*, bool)':
/srv/buildbot/synergy/1.4-linux32/build/src/lib/base/CLog.cpp:213: undefined reference to `kAppVersion'
collect2: ld returned 1 exit status
make[2]: *** [../../bin/debug/synergyd] Error 1
make[1]: *** [src/cmd/synergyd/CMakeFiles/synergyd.dir/all] Error 2
make: *** [all] Error 2

完全なコードは、リポジトリから参照できます。

4

3 に答える 3

4

要するに、実際の問題:archとの間の循環ライブラリ依存関係synergy。また、 base実際にはcommonライブラリにリンクされていませんでした (の CMakeLists.txt 内base)。

興味深いことに、これはライブラリの CMakeLists.txt ファイルの構成の問題が原因でした。synergydこれは、追加した新しいアプリケーションの CMakeLists.txt とは関係ありません。

問題は、新しい呼び出しが他のライブラリのクラスに追加された場合に、ライブラリを相互にリンクしていなかったことです。ただし、現在、循環リンクに問題があるようです。

たとえば、私は追加することができました...

if (UNIX)
    target_link_libraries(arch synergy)
endif()

...ライブラリ内の何かを呼び出すように、archライブラリ内のCMakeLists.txtに。しかし、これは無効です。すでに で何かを呼び出しているからです。archsynergysynergyarch

どうやら、これは Windows では関係ありません。

以前は正常にコンパイルされていたすべての古いコードであり、他のアプリケーションでもまだ実行されているため、これが発生し始めた原因はよくわかりません。CDaemonApp が行っていること (または両方の組み合わせ) ではなく、最近 CArch からボイラー プレートが削除されたことに関係があると思われます。

アップデート

arch誰かが気になる場合に備えて ;-) -- と の間のお粗末な循環ライブラリ依存関係と、 が含まれていなかっsynergyたという事実との関係に関係していると思います-- つまり、他の時点で含まれていたことを意味します。奇妙な未定義の参照エラーを引き起こします。CDaemonApp.cppCApp.h

これを適切に解決するために、問題の核心であると思われる循環依存関係を削除しました。

更新 2

コードが完全にコンパイルされるようになりました。

私はまだ最後のエラーを見ていました(この質問のトピック):

[ 90%] Building CXX object src/cmd/synergyd/CMakeFiles/synergyd.dir/synergyd.o
Linking CXX executable ../../../../../bin/debug/synergyd
../../../../../lib/debug/libbase.a(CLog.o): In function `CLog::insert(ILogOutputter*, bool)':
/home/nick/Projects/synergy/branches/1.4/src/lib/base/CLog.cpp:213: undefined reference to `kAppVersion'
collect2: ld returned 1 exit status
make[2]: *** [../../bin/debug/synergyd] Error 1
make[1]: *** [src/cmd/synergyd/CMakeFiles/synergyd.dir/all] Error 2
make: *** [all] Error 2

これは単に、baseライブラリがライブラリにリンクしていないことが原因でしたcommon。ベースの CMakeLists.txt ファイルに次のコードを追加すると、これが修正されました。

if (UNIX)
    target_link_libraries(base common)
endif()

なぜこれが起こり始めたのか正確にはまだわかりませんが、修正されてうれしいです.

アップデート 3

そしてここにコミットがあります:r1354

于 2012-04-06T23:12:02.950 に答える
2

まず、少なくとも g++ では、リンクの順序が重要です。Aのシンボルを使用する場合はB、 の後Bに記載する必要がありますAg++ ... -lA -lB

も表示されますundefined reference to vtable for XExitApp。このエラーは、定義されていない仮想関数があることを意味しますXExitApp。その関数を定義したくない場合は、追加して純粋仮想にします= 0

于 2012-04-06T10:05:11.037 に答える
0

set(inc...私が気づいた唯一のことは、../../lib/synergy のセクションに「../../lib/synergy」がないことでし/synergyd/CMakeLists.txtた。これが問題に関連しているかどうかは、私が推測することしかできません。

取得しているすべてのリンク エラーは、リンカが探しているシンボルを見つけられないことが原因のようです。これの通常の理由は、関連する .o ファイルが存在しないか、ビルドに含まれていないか、不適切にコンパイルされていることです。

まず、CMakeList.txt ファイルをクリーニングし、既知の動作バージョンと可能な限り一致するように変更し、すべてのコンパイラ/警告をオンにしてすべてを再構築します。それが機能しない場合 (同じエラーまたは別のエラーのいずれか)、機能するものと機能しないものをより詳しく調べます。あなたは、Windows ビルドは機能すると言いましたが、Linux ビルドは機能しません。2つの違いと、どちらが問題を説明できるか。同様に、適切にビルドされる 1 つの同様のプロジェクト: 2 つのプロジェクトの違いは何ですか。

于 2012-04-06T13:29:32.820 に答える