4

複数のプラットフォーム用に C++ を開発しているため、ビルド プロセスに SCons を使用することを調査しています。ビルド構成は 99%完了していますが、Windows でプリコンパイル済みヘッダー ファイルに関係する非常に奇妙なエラーが発生していますさらに奇妙なのは、それが 1 つのプロジェクトでのみ発生することです。

このプロジェクトの SConscript ファイルには、Windows で PCH をコンパイルするための次のものが含まれています。

if env['PLATFORM'] == 'win32':
    env['PCH'] = env.PCH('MyPCH-LSCommon.pch', 'Common/src/MyPCH.h')[0]
    env['PCHSTOP'] = '"MyPCH.h"'

また、プロジェクト内のすべてのファイルに MyPCH.h を強制的に含めるようにコンパイラ フラグを設定しています。

if env['PLATFORM'] == 'win32':
    cxxflags = [ '/FI"MyPCH.h"' ]

すべてがうまくいき、完全にうまくコンパイルされます。次のようなリンカ エラーのページやページが表示されるのは、最終的な DLL リンク ステージまでではありません。

error LNK2001: unresolved external symbol "private: static class
boost::asio::detail::tss_ptr<class boost::asio::detail::call_stack<class 
boost::asio::detail::win_iocp_io_service>::context> boost::asio::detail::call_stack<class 
boost::asio::detail::win_iocp_io_service>::top_" 
(?top_@?$call_stack@Vwin_iocp_io_service@detail@asio@boost@@@detail@asio@boost@@0V?$tss_ptr@
Vcontext@?$call_stack@Vwin_iocp_io_service@detail@asio@boost@@@detail@asio@boost@@@234@A)

と:

     error LNK2001: unresolved external symbol "private: static class 
boost::asio::detail::winsock_init<2,0> boost::asio::detail::winsock_init<2,0>::instance_" 
(?instance_@?$winsock_init@$01$0A@@detail@asio@boost@@0V1234@A)

これは不可解です。なぜなら、私がリンク警告を受け取っているクラスはどれもboost::asioを使用していないからです.

さらに困惑するのは、プリコンパイル済みヘッダー ファイルのコンパイルを無効にしても、インクルードを強制すると、すべてが正常にコンパイルおよびリンクされることです。それはただ永遠におかしくなります。

これらのリンカ エラーの原因について何か手がかりを持っている人はいますか?

前もって感謝します。

- - 編集 - -

SCons が PCH を構築するために出力しているコマンド ラインを次に示します (マイナス インクルード パス)。

    cl /nologo /W4 /Od /RTC1 /MDd /TP /EHsc /FD /RTC1 /RTCc /Gy /openmp /TP 
/Fd"\vc80.pdb" /nologo /Wp64 /wd4231 /wd4616 /errorReport:prompt /Zm256 /MDd /Od
/FI"CedrusPCH.h" /DOS_WINDOWS=OS_WINDOWS /D_WIN32 /DWIN32 /D_WIN32_WINNT=0X500 /D_WINDOWS 
/D_UNICODE /DBOOST_ALL_DYN_LINK /DBOOST_REGEX_DYN_LINK /DBOOST_LIB_DIAGNOSTIC 
/D_VC80_UPGRADE=0x710 /DUNICODE /DWXUSINGDLL /DwxUSE_SERVICE_DISCOVERY=1 /D_DEBUG /D_DEBUG 
/DSL_ENABLE_NETWORKING=1 /DWXMAKINGDLL_LSCOMMON /DSLSDK_USEDLL 
/c C:\Projects\licenser\Common\src\CedrusPCH.h /Foscons-out\dbg\obj\CedrusPCH-LSCommon.obj
/Yc"CedrusPCH.h" /Fpscons-out\dbg\obj\CedrusPCH-LSCommon.pch /ZI CedrusPCH.h

コンパイル中のファイルのコマンド ラインを次に示します (ここでもインクルード パスは省略しています)。

cl /Foscons-out\dbg\obj\Licenser\src\secure\windows_crypto
\PlatformCryptoKeyProvider_wincrypt.obj /c C:\Projects\licenser\Licenser\src\secure
\windows_crypto\PlatformCryptoKeyProvider_wincrypt.cpp /nologo /W4 /Od /RTC1 /MDd /TP 
/EHsc /FD /RTC1 /RTCc /Gy /openmp /TP /Fd"\vc80.pdb" /nologo /Wp64 /wd4231 /wd4616 
/errorReport:prompt /Zm256 /MDd /Od /FI"CedrusPCH.h" /nologo /W4 /Od /RTC1 /MDd 
/DOS_WINDOWS=OS_WINDOWS /D_WIN32 /DWIN32 /D_WIN32_WINNT=0X500 /D_WINDOWS /D_UNICODE 
/DBOOST_ALL_DYN_LINK /DBOOST_REGEX_DYN_LINK /DBOOST_LIB_DIAGNOSTIC /D_VC80_UPGRADE=0x710 
/DUNICODE /DWXUSINGDLL /DwxUSE_SERVICE_DISCOVERY=1 /D_DEBUG /D_DEBUG 
/DSL_ENABLE_NETWORKING=1 /DWXMAKINGDLL_LSCOMMON /DSLSDK_USEDLL /D_USRDLL /D_WINDLL 
 /Yu"CedrusPCH.h" /Fpscons-out\dbg\obj\CedrusPCH-LSCommon.pch /ZI
PlatformCryptoKeyProvider_wincrypt.cpp

最後に、リンク コマンド ラインを次に示します。

link /nologo /MACHINE:X86 /DEBUG -manifest /dll /out:scons-out\dbg\obj\LSCommon.dll 
/implib:scons-out\dbg\obj\LSCommon.lib /LIBPATH:scons-out\dbg\lib 
/LIBPATH:C:\Projects\licenser\scons-out\dbg\lib /LIBPATH:scons-out\dbg\obj 
/LIBPATH:. /LIBPATH:C:\Projects\licenser /LIBPATH:C:\Projects\licenser\scons-out\dbg\obj 
/LIBPATH:C:\Projects\wxWidgets\lib\vc_dll_vc8 /LIBPATH:C:\Projects\boost\install\lib 
"/LIBPATH:C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Lib" 
"/LIBPATH:C:\Program Files\Bonjour SDK\lib\win32" unicows.lib winmm.lib comctl32.lib 
rpcrt4.lib ws2_32.lib oleacc.lib kernel32.lib user32.lib gdi32.lib winspool.lib 
comdlg32.lib advapi32.lib shell32.lib oleacc.lib ole32.lib oleaut32.lib uuid.lib 
odbc32.lib odbccp32.lib boost_signals-vc80-mt-gd-1_39.lib boost_system-vc80-mt-gd-1_39.lib 
boost_date_time-vc80-mt-gd-1_39.lib boost_regex-vc80-mt-gd-1_39.lib 
boost_wserialization-vc80-mt-gd-1_39.lib boost_serialization-vc80-mt-gd-1_39.lib 
boost_thread-vc80-mt-gd-1_39.lib wxbase28ud.lib wxbase28ud_net.lib wxbase28ud_xml.lib 
wxmsw28ud_adv.lib wxmsw28ud_aui.lib wxmsw28ud_core.lib wxmsw28ud_html.lib wxmsw28ud_qa.lib 
wxmsw28ud_richtext.lib wxmsw28ud_xrc.lib LSBase.lib disphelper.lib Crypt32.lib 
/PDB:scons-out\dbg\obj\LSCommon.pdb /DEBUG 
scons-out\dbg\obj\Licenser\src\dll_template_instantiation_export_LSCommon.obj 
scons-out\dbg\obj\Licenser\src\secure\ConcreteMessageSigningAlgorithm_DSA_with_SHA1.obj 
scons-out\dbg\obj\Licenser\src\secure\CryptoObjectFactory.obj 
scons-out\dbg\obj\Licenser\src\secure\EntropyCalculation.obj 
scons-out\dbg\obj\Licenser\src\data\LSAccount.obj 
scons-out\dbg\obj\Licenser\src\data\LSAccountHistory.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSAccountHistoryRequestPacket.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSAccountRequestPacket.obj 
scons-out\dbg\obj\Licenser\src\data\LSActivation.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSActivationRequestPacket.obj 
scons-out\dbg\obj\Licenser\src\data\LSBlob.obj 
scons-out\dbg\obj\Licenser\src\data\LSCompositePrimaryKey.obj 
scons-out\dbg\obj\Licenser\src\data\LSDatabaseElementBase.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSDoActivateReplyPacket.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSDoActivateRequestPacket.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSDoManualActivateReplyPacket.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSDoManualActivateRequestPacket.obj 
scons-out\dbg\obj\Licenser\src\data\LSLicense.obj 
scons-out\dbg\obj\Licenser\src\data\LSLicenseHistory.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSLicenseHistoryRequestPacket.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSLicenseRequestPacket.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSLoginReplyPacket.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSLoginRequestPacket.obj 
scons-out\dbg\obj\Licenser\src\data\LSMachine.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSMachineRequestPacket.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSNet.obj 
scons-out\dbg\obj\Licenser\src\data\LSPhyActivation.obj 
scons-out\dbg\obj\Licenser\src\data\deprecated_streamables\LSPhyActivation_LegacyStreamingHelper.obj 
scons-out\dbg\obj\Licenser\src\data\LSPrimaryKey.obj 
scons-out\dbg\obj\Licenser\src\data\LSPrimaryKeyDefinitions.obj 
scons-out\dbg\obj\Licenser\src\data\LSProduct.obj 
scons-out\dbg\obj\Licenser\src\data\LSProductHistory.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSProductHistoryRequestPacket.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSProductRequestPacket.obj 
scons-out\dbg\obj\Licenser\src\data\LSSimplePrimaryKey.obj 
scons-out\dbg\obj\Licenser\src\data\LSUser.obj 
scons-out\dbg\obj\Licenser\src\data\LSUserHistory.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSUserHistoryRequestPacket.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSUserRequestPacket.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\streaming_versioning\StreamableClassInfoVersionTranslator.obj
scons-out\dbg\obj\Licenser\src\data\deprecated_streamables\LSProduct_deprecated_v_2.obj 
scons-out\dbg\obj\Licenser\src\secure\deprecated_streamables\DSA.obj 
scons-out\dbg\obj\Licenser\src\secure\deprecated_streamables\DSAKeyPair.obj 
scons-out\dbg\obj\Licenser\src\secure\deprecated_streamables\DSAPublicKey.obj 
scons-out\dbg\obj\Licenser\src\secure\deprecated_streamables\Hash.obj 
scons-out\dbg\obj\Licenser\src\secure\deprecated_streamables\SHA1.obj 
scons-out\dbg\obj\Licenser\src\server_daemon\LSActivationApprovalStrategy.obj 
scons-out\dbg\obj\Licenser\src\data\LSDatabaseElementT.obj 
scons-out\dbg\obj\Licenser\src\data\LSPairPrimaryKeyT.obj 
scons-out\dbg\obj\Licenser\src\data\LSSimplePrimaryKeyT.obj 
scons-out\dbg\obj\Licenser\src\secure\windows_crypto\PlatformCryptoKeyProvider_wincrypt.obj
scons-out\dbg\obj\Licenser\src\secure\windows_crypto\Scoped_RAII_AutoReleaseWincryptHandleFactory.obj

また、PCH ヘッダーは個々のファイルごとに明示的に含まれているわけではありませんが、コマンド ライン オプションでは、プロジェクトでコンパイルされたすべてのファイルに PCH を強制的に含める /FI があります。

4

2 に答える 2

2

私は自分の問題を解決したようです。ヘッダー ファイルをプリコンパイルすると、cl.exe によって .obj ファイルが生成されます。ブーストの内部マジックを使用して Windows で必要なライブラリに自動的にリンクし、ブースト ヘッダーの #include もプリコンパイル済みヘッダーに含まれているため、これらのリンクも .obj ファイルに含まれています。残念ながら、この .obj ファイルは、(この場合は .dll を作成するために) リンクする必要がある .obj ファイルのリストに追加されません。

それが機能したのは、PCH のコンパイル中に生成された .obj ファイルを LINKFLAGS 引数に手動で追加することでした。これを100%実行すると、私が抱えていた問題が完全に解決されます。msvc.py ツールを更新して SCons にパッチを送信するときが来たのかもしれません。

于 2009-06-17T01:02:17.037 に答える
0

プリコンパイル済みヘッダーをビルドするときに存在するコンパイル時の定義が 2 つあります。

/D_USRDLL
/D_WINDLL

私の知る限り、これらは MFC の遺物です。私はそれらについて何も知りませんが、wxWidgets がそれらに何らかの依存関係を持っていたとしても驚かないでしょう。Boostがそうするかどうかは疑問です(しかし、私も見ていません)。

于 2009-06-17T01:08:33.453 に答える