SCons, Boost :: ASIO, Precompiled Windows Headers and Linker Errors

I am studying the use of SCons for our build process, as we are developing C ++ for several platforms. I am 99% in the build configuration, but I ran into a VERY weird bug in Windows related to a precompiled header file. Even stranger is that this happens in only one project.

In the SConscript file for this project, I have the following to compile PCH on windows:

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

I also have a compiler flag set to force MyPCH.h to be included in all project files:

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

Everything goes and compiles absolutely fine. Only at the stage of the final DLL link do I get pages and linker error pages, for example:

 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 ) 

and

  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 ) 

This is bewildering because none of the classes with which I receive warnings from links even use boost :: asio, although it is included in the precompiled header file and up the chain in some #includes.

Even more troubling is that if I disable compilation of the precompiled header file, but still force it to turn on, everything compiles and the links are very good. It just excites forever.

Does anyone know what might cause these linker errors?

Thanks in advance.

--- EDIT ---

Here's the command line that SCons spits out to create PCH (Minus Include Paths):

  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 

Here is the command line for the compiled file (again minus includes paths):

 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 

And finally, here is the command line link:

 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 

In addition, the PCH header is not explicitly included by each individual file, but in the command line options, I have / FI, which contains PCH for each file compiled in the project.

+4
source share
2 answers

I seem to have solved my problem. When you precompile the header file, cl.exe creates the .obj file. Since we use built-in internal magic to automatically link to the libraries we need on Windows, and our boost #includes header is also in the precompiled header, these links are also included in the .obj file. Unfortunately, this .obj file is not added to the list of .obj files that need to be linked (to create a .dll in this case).

What happened was manually adding the .obj file generated at PCH compilation to the LINKFLAGS argument. Doing this 100% completely solves the problem I am facing. Maybe it's time to update msvc.py and send the patch to SCons!

+2
source

When compiling, 2 are defined when building precompiled headers:

 /D_USRDLL /D_WINDLL 

As far as I know, these are relics of the MFC. I don’t know anything about them, but I won’t be surprised if wxWidgets has some dependencies on them. I doubt Boost (but I didn't look either).

0
source

Source: https://habr.com/ru/post/1286259/


All Articles