From: <ag...@us...> - 2010-04-03 18:22:50
|
Revision: 1232 http://zoolib.svn.sourceforge.net/zoolib/?rev=1232&view=rev Author: agreen Date: 2010-04-03 18:22:43 +0000 (Sat, 03 Apr 2010) Log Message: ----------- Add ZCompat_MSVCStaticLib.h, see that file for details. Add ZMACRO_MSVCStaticLib_Reference and ZMACRO_MSVCStaticLib_cpp to appropriate files (static factories used on windows). Modified Paths: -------------- trunk/zoolib/source/cxx/old/zoolib/ZDC_GDI.cpp trunk/zoolib/source/cxx/old/zoolib/ZDC_GDI.h trunk/zoolib/source/cxx/zoolib/ZFunctionChain.h trunk/zoolib/source/cxx/zoolib/ZGRgnRep_HRGN.cpp trunk/zoolib/source/cxx/zoolib/ZGRgnRep_HRGN.h trunk/zoolib/source/cxx/zoolib/ZNet_Internet_WinSock.cpp trunk/zoolib/source/cxx/zoolib/ZNet_Internet_WinSock.h trunk/zoolib/source/cxx/zoolib/ZStreamRWCon_SSL_Win.cpp trunk/zoolib/source/cxx/zoolib/ZStreamRWCon_SSL_Win.h trunk/zoolib/source/cxx/zoolib/ZTextCoder_Win.cpp trunk/zoolib/source/cxx/zoolib/ZTextCoder_Win.h trunk/zoolib/source/cxx/zoolib/ZUnicode_Normalize_Win.cpp trunk/zoolib/source/cxx/zoolib/ZUnicode_Normalize_Win.h Added Paths: ----------- trunk/zoolib/source/cxx/zoolib/ZCompat_MSVCStaticLib.h Modified: trunk/zoolib/source/cxx/old/zoolib/ZDC_GDI.cpp =================================================================== --- trunk/zoolib/source/cxx/old/zoolib/ZDC_GDI.cpp 2010-04-03 16:39:11 UTC (rev 1231) +++ trunk/zoolib/source/cxx/old/zoolib/ZDC_GDI.cpp 2010-04-03 18:22:43 UTC (rev 1232) @@ -22,6 +22,9 @@ #if ZCONFIG_API_Enabled(DC_GDI) +#include "zoolib/ZCompat_MSVCStaticLib.h" +ZMACRO_MSVCStaticLib_cpp(DC_GDI) + #include "zoolib/ZCompat_algorithm.h" // For min #include "zoolib/ZFunctionChain.h" #include "zoolib/ZMemory.h" Modified: trunk/zoolib/source/cxx/old/zoolib/ZDC_GDI.h =================================================================== --- trunk/zoolib/source/cxx/old/zoolib/ZDC_GDI.h 2010-04-03 16:39:11 UTC (rev 1231) +++ trunk/zoolib/source/cxx/old/zoolib/ZDC_GDI.h 2010-04-03 18:22:43 UTC (rev 1232) @@ -36,6 +36,9 @@ #if ZCONFIG_API_Enabled(DC_GDI) +#include "zoolib/ZCompat_MSVCStaticLib.h" +ZMACRO_MSVCStaticLib_Reference(DC_GDI) + #include "zoolib/ZCompat_Win.h" #include "zoolib/ZThreadOld.h" Added: trunk/zoolib/source/cxx/zoolib/ZCompat_MSVCStaticLib.h =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZCompat_MSVCStaticLib.h (rev 0) +++ trunk/zoolib/source/cxx/zoolib/ZCompat_MSVCStaticLib.h 2010-04-03 18:22:43 UTC (rev 1232) @@ -0,0 +1,112 @@ +/* ------------------------------------------------------------------------------------------------- +Copyright (c) 2010 Andrew Green +http://www.zoolib.org + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software +and associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES +OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------------------------- */ +#ifndef __ZCompat_MSVCStaticLib__ +#define __ZCompat_MSVCStaticLib__ 1 +#include "zconfig.h" + +/** +\file +\sa ZFunctionChain.h +\section Background + +Static variables in a translation unit are initialized before any regular code in the +translation unit executes. In practice the initialization happens when the containing +executable or dynamic library is loaded. When your main() is called, or your call to +LoadLibrary/dlopen completes, any static variables will have been initialized. + +\section TheProblem The Problem +It can be convenient to place the object code from multiple translation units in a single +file, a static library conventionally named with a .lib or .a suffix. The MSVC linker does +dependency analysis on static libraries and will not include code that is not referenced +by the including entity. The common pattern of using a static variable to declare and cause +the registration of a factory object can fail in this circumstance -- the MSVC linker +deems the static as being unreachable and strips it from the result. + +\section Solutions +A useful google search: http://www.google.com/search?q=msvc+factory+static+library + +One solution is to set the /OPT:NOREF linker flag on the including entity. However, this is +an all or nothing setting, and will require that all included libraries be fully linkable. + +If something in the file containing the static is referenced (directly or indirectly) by +the including entity, then by the language rules the static itself must be preserved. + +The most basic approach is to put a dummy variable in the file, and reference it from +somewhere known to be considered reachable. + +Another approach is to use the /include linker flag to reference an entity in the problem file. +This can be done in the source itself. Assuming an entity named DummyForLinkProblem: +\code #pragma comment(linker, "/include:DummyForLinkProblem") \endcode + +\section ZooLibSolution ZooLib's Solution +ZooLib entities currently affected by this problem are those in ZFile_Win.cpp, ZGRgnRep_HRGN.cpp, +ZNet_Internet_WinSock.cpp, ZStreamRWCon_SSL_Win.cpp, ZTextCoder_Win.cpp +and ZUnicode_Normalize_Win.cpp. + +We #include ZCompat_MSVCStaticLib.h in the corresponding header files, and put in each a +ZMACRO_MSVCStaticLib_Reference(ModifiedFileName). In the cpp files we put a +ZMACRO_MSVCStaticLib_cpp(ModifiedFileName). The ModifiedFileName is generally the +filename with the leading Z and file extension removed, the same style of name is +used in ZCONFIG_API_XXX macros. + +To ensure that your executable or library does not strip these entities, simply #include +the appropriate header file from known referenced code in your including entity. This will +cause a non-executing reference to occur, and things will work as expected. +*/ + +// ================================================================================================= +#pragma mark - +#pragma mark * ZCompat_MSVCStaticLib + +#if ZCONFIG(Compiler, MSVC) + +#define ZMACRO_MSVCStaticLib_Reference(a) \ + namespace ZooLib { \ + namespace MSVCStaticLib { \ + namespace a { \ + extern const int DummyInteger; \ + namespace /* anonymous */ { \ + int ReferenceDummyInteger(); \ + int ReferenceDummyInteger() { return DummyInteger; } \ + } /* anonymous namespace*/ \ + } /* namespace a */ \ + } /* namespace MSVCStaticLib */ \ + } /* namespace ZooLib */ + +#define ZMACRO_MSVCStaticLib_cpp(a) \ + namespace ZooLib { \ + namespace MSVCStaticLib { \ + namespace a { \ + const int DummyInteger = 0; \ + } /* namespace a */ \ + } /* namespace MSVCStaticLib */ \ + } /* namespace ZooLib */ + +#endif // ZCONFIG(Compiler, MSVC) + +#if !defined(ZMACRO_MSVCStaticLib_Reference) + #define ZMACRO_MSVCStaticLib_Reference(a) +#endif + +#if !defined(ZMACRO_MSVCStaticLib_cpp) + #define ZMACRO_MSVCStaticLib_cpp(a) +#endif + +#endif // __ZCompat_MSVCStaticLib__ Modified: trunk/zoolib/source/cxx/zoolib/ZFunctionChain.h =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZFunctionChain.h 2010-04-03 16:39:11 UTC (rev 1231) +++ trunk/zoolib/source/cxx/zoolib/ZFunctionChain.h 2010-04-03 18:22:43 UTC (rev 1232) @@ -24,6 +24,14 @@ NAMESPACE_ZOOLIB_BEGIN +/** +\file +If you're using the MSVC linker and putting a factory in a static library, be aware that +the statically-initialized factory will not be considered active code unless some other +part of the containing translation unit is active. See ZCompat_MSVCStaticLib.h for +more discussion and suggested workarounds. +*/ + // ================================================================================================= #pragma mark - #pragma mark * ZFunctionChain_T Modified: trunk/zoolib/source/cxx/zoolib/ZGRgnRep_HRGN.cpp =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZGRgnRep_HRGN.cpp 2010-04-03 16:39:11 UTC (rev 1231) +++ trunk/zoolib/source/cxx/zoolib/ZGRgnRep_HRGN.cpp 2010-04-03 18:22:43 UTC (rev 1232) @@ -22,6 +22,8 @@ #if ZCONFIG_API_Enabled(GRgnRep_HRGN) +ZMACRO_MSVCStaticLib_cpp(GRgnRep_HRGN) + #include "zoolib/ZFunctionChain.h" #include <vector> Modified: trunk/zoolib/source/cxx/zoolib/ZGRgnRep_HRGN.h =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZGRgnRep_HRGN.h 2010-04-03 16:39:11 UTC (rev 1231) +++ trunk/zoolib/source/cxx/zoolib/ZGRgnRep_HRGN.h 2010-04-03 18:22:43 UTC (rev 1232) @@ -37,6 +37,9 @@ #if ZCONFIG_API_Enabled(GRgnRep_HRGN) +#include "zoolib/ZCompat_MSVCStaticLib.h" +ZMACRO_MSVCStaticLib_Reference(GRgnRep_HRGN) + #include "zoolib/ZCompat_Win.h" NAMESPACE_ZOOLIB_BEGIN Modified: trunk/zoolib/source/cxx/zoolib/ZNet_Internet_WinSock.cpp =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZNet_Internet_WinSock.cpp 2010-04-03 16:39:11 UTC (rev 1231) +++ trunk/zoolib/source/cxx/zoolib/ZNet_Internet_WinSock.cpp 2010-04-03 18:22:43 UTC (rev 1232) @@ -22,6 +22,8 @@ #if ZCONFIG_API_Enabled(Net_Internet_WinSock) +ZMACRO_MSVCStaticLib_cpp(Net_Internet_WinSock) + #include "zoolib/ZCompat_cmath.h" #include "zoolib/ZFunctionChain.h" #include "zoolib/ZMemory.h" @@ -73,6 +75,32 @@ // ================================================================================================= #pragma mark - +#pragma mark * InitializeWinSock + +namespace ZANONYMOUS { + +class InitializeWinSock + { +public: + InitializeWinSock() + { + // Low order byte is major version number, high order byte is minor version number. + int result = ::WSAStartup(0x0002, &fWSADATA); + if (result) + ZDebugLogf(2, ("WSAStartup got error %d", GetLastError())); + } + + ~InitializeWinSock() + { ::WSACleanup(); } + +private: + WSADATA fWSADATA; + } sInitializeWinSock; + +} // anonymous namespace + +// ================================================================================================= +#pragma mark - #pragma mark * ZNet_Internet_WinSock ZNet::Error ZNet_Internet_WinSock::sTranslateError(int inNativeError) @@ -93,33 +121,6 @@ // ================================================================================================= #pragma mark - -#pragma mark * ZNet_Internet_WinSock::InitHelper__ - -class ZNet_Internet_WinSock::InitHelper__ - { -public: - InitHelper__(); - ~InitHelper__(); -private: - WSADATA fWSADATA; - static InitHelper__ spInitHelper__; - }; - -ZNet_Internet_WinSock::InitHelper__ ZNet_Internet_WinSock::InitHelper__::spInitHelper__; - -ZNet_Internet_WinSock::InitHelper__::InitHelper__() - { - // Low order byte is major version number, high order byte is minor version number. - int result = ::WSAStartup(0x0002, &fWSADATA); - if (result) - ZDebugLogf(2, ("WSAStartup got error %d", GetLastError())); - } - -ZNet_Internet_WinSock::InitHelper__::~InitHelper__() - { ::WSACleanup(); } - -// ================================================================================================= -#pragma mark - #pragma mark * ZNetNameLookup_Internet_WinSock ZNetNameLookup_Internet_WinSock::ZNetNameLookup_Internet_WinSock( Modified: trunk/zoolib/source/cxx/zoolib/ZNet_Internet_WinSock.h =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZNet_Internet_WinSock.h 2010-04-03 16:39:11 UTC (rev 1231) +++ trunk/zoolib/source/cxx/zoolib/ZNet_Internet_WinSock.h 2010-04-03 18:22:43 UTC (rev 1232) @@ -36,6 +36,9 @@ #if ZCONFIG_API_Enabled(Net_Internet_WinSock) +#include "zoolib/ZCompat_MSVCStaticLib.h" +ZMACRO_MSVCStaticLib_Reference(Net_Internet_WinSock) + #include <vector> #include <winsock.h> @@ -50,8 +53,6 @@ { public: static ZNet::Error sTranslateError(int inNativeError); -private: - class InitHelper__; }; // ================================================================================================= Modified: trunk/zoolib/source/cxx/zoolib/ZStreamRWCon_SSL_Win.cpp =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZStreamRWCon_SSL_Win.cpp 2010-04-03 16:39:11 UTC (rev 1231) +++ trunk/zoolib/source/cxx/zoolib/ZStreamRWCon_SSL_Win.cpp 2010-04-03 18:22:43 UTC (rev 1232) @@ -22,6 +22,8 @@ #if ZCONFIG_SPI_Enabled(Win) +ZMACRO_MSVCStaticLib_cpp(StreamRWCon_SSL_Win) + #include "zoolib/ZFunctionChain.h" #include "zoolib/ZMemory.h" #include "zoolib/ZStreamerRWCon_SSL.h" Modified: trunk/zoolib/source/cxx/zoolib/ZStreamRWCon_SSL_Win.h =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZStreamRWCon_SSL_Win.h 2010-04-03 16:39:11 UTC (rev 1231) +++ trunk/zoolib/source/cxx/zoolib/ZStreamRWCon_SSL_Win.h 2010-04-03 18:22:43 UTC (rev 1232) @@ -27,6 +27,9 @@ #if ZCONFIG_SPI_Enabled(Win) +#include "zoolib/ZCompat_MSVCStaticLib.h" +ZMACRO_MSVCStaticLib_Reference(StreamRWCon_SSL_Win) + #include "zoolib/ZCompat_Win.h" #include <vector> Modified: trunk/zoolib/source/cxx/zoolib/ZTextCoder_Win.cpp =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZTextCoder_Win.cpp 2010-04-03 16:39:11 UTC (rev 1231) +++ trunk/zoolib/source/cxx/zoolib/ZTextCoder_Win.cpp 2010-04-03 18:22:43 UTC (rev 1232) @@ -22,6 +22,8 @@ #if ZCONFIG_API_Enabled(TextCoder_Win) +ZMACRO_MSVCStaticLib_cpp(TextCoder_Win) + #include "zoolib/ZFunctionChain.h" #include "zoolib/ZThread.h" #include "zoolib/ZUnicode.h" Modified: trunk/zoolib/source/cxx/zoolib/ZTextCoder_Win.h =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZTextCoder_Win.h 2010-04-03 16:39:11 UTC (rev 1231) +++ trunk/zoolib/source/cxx/zoolib/ZTextCoder_Win.h 2010-04-03 18:22:43 UTC (rev 1232) @@ -36,6 +36,9 @@ #if ZCONFIG_API_Enabled(TextCoder_Win) +#include "zoolib/ZCompat_MSVCStaticLib.h" +ZMACRO_MSVCStaticLib_Reference(TextCoder_Win) + #include "zoolib/ZCompat_Win.h" NAMESPACE_ZOOLIB_BEGIN Modified: trunk/zoolib/source/cxx/zoolib/ZUnicode_Normalize_Win.cpp =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZUnicode_Normalize_Win.cpp 2010-04-03 16:39:11 UTC (rev 1231) +++ trunk/zoolib/source/cxx/zoolib/ZUnicode_Normalize_Win.cpp 2010-04-03 18:22:43 UTC (rev 1232) @@ -22,6 +22,8 @@ #if ZCONFIG_SPI_Enabled(Win) +ZMACRO_MSVCStaticLib_cpp(Unicode_Normalize_Win) + #include "zoolib/ZCompat_Win.h" #include "zoolib/ZFunctionChain.h" Modified: trunk/zoolib/source/cxx/zoolib/ZUnicode_Normalize_Win.h =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZUnicode_Normalize_Win.h 2010-04-03 16:39:11 UTC (rev 1231) +++ trunk/zoolib/source/cxx/zoolib/ZUnicode_Normalize_Win.h 2010-04-03 18:22:43 UTC (rev 1232) @@ -23,4 +23,7 @@ #include "zconfig.h" #include "ZUnicode_Normalize.h" +#include "zoolib/ZCompat_MSVCStaticLib.h" +ZMACRO_MSVCStaticLib_Reference(Unicode_Normalize_Win) + #endif // __ZUnicode_Normalize_Win__ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |