This forum has been archived. Please start a new discussion on GitHub.

Static linking (again)

Hi Zeroc,

I realise this has been asked before ... just wondering if there are any plans whatsoever to support static linkage in the future? Aside from cleaner patch deployment, there's little benefit for me in using dynamic linking, but for internet-deployed Windows clients there's considerable risk.

My two concerns are 1. DLL substitution - ie Ice source is freely available so an attacker could rebuild and deploy ice30.dll hijacking application calls with their own to subvert application logic (eg. activation) - and 2. call sniffing with tools like stracent to reveal unprivileged information (eg. cleartext logons/passwords). These are real issues for an uncontrolled client environment but a static standalone binary would only expose the communication protocol (excluding universal Windows remote code injection risks) ...



  • bernard
    bernard Jupiter, FL
    Hi Joe,

    At this time, we have no plan to add static linking to Ice. The addition of such features really depend on requests from commercial customers.

    Also, Ice-E supports static linking (and Windows); maybe you can use Ice-E instead of Ice for your internet-deployed Windows clients.

    Best regards,
  • Hi Bernard,

    I did look at Ice-E briefly, however I think I'll just port Ice to a static lib if you guys have no strong objections. I ported IceUtil as a test run without any significant drama and jotted down the process below if anyone's interested. I realise ZeroC won't support this, but to be fair it seems like a trivial addition since most of the supporting preprocessor directives and module structures are in place for this.

    My notes below on how I did this for IceUtil - I intend to continue for the rest of Ice but might wait for 3.1 to save forking too early. My changes were based on Windows, specifically VC.Net 2003 build environment...
    1. Convert the IceUtil.dsp to VC.Net 2003 solution + vcproj.
    2. Clone the .vcproj to iceutils.vcproject, modify build properties as follows (shown for Debug, c&p for Release)
       - General\Output Directory = .\DebugStatic
       - General\Intermediate Directory = .\DebugStatic
       - General\Configuration Type = Static Library (.lib)
       - C/C++\Preprocessor\Preprocessor Definitions = ICE_UTIL_API_EXPORTS;ICE_STATIC_LIBS;_CONSOLE;_DEBUG;WIN32_LEAN_AND_MEAN
       - C/C++\Code Generation\Runtime Library = Multi-threaded Debug (/MTd)
       - C/C++\Precompiled Headers\Precompiled Header File = .\DebugStatic/iceutil.pch
       - C/C++\Output Files\ASM List Location = .\DebugStatic/
       - C/C++\Output Files\Object File Name = .\DebugStatic/
       - C/C++\Output Files\Program Database File Name = .\DebugStatic/
       - C/C++\Librarian\General\Output File = .\DebugStatic/iceutilsd.lib
       - C/C++\Browse Information\General\Output File = .\DebugStatic/iceutil.bsc
       - Build Events\Post-Build Event\Command Line = copy "$(OutDir)"\iceutilsd.lib ..\..\lib
    Change lines 102 through 104 of IceUtil/Config.h to read:
    ///#   if !defined(_DLL) || !defined(_MT)
    ///#       error "Only multi-threaded DLL libraries can be used with Ice!"
    ///#   endif
    #   if (!defined(_DLL) && !defined(ICE_STATIC_LIBS)) || !defined(_MT)
    #       error "Only multi-threaded libraries can be used with Ice!"
    #   endif
    (a) when converting .dsp to .vcproj files, make sure that preprocessor defines are not re-specified at file level, but only at project level. Mine defaulted to including defines at file level as well as project level and so adding ICE_STATIC_LIBS and removing _USRDLL at project level did nothing (!!) for a short while

    Static clients link against iceutilsd.lib and define macro as follows :-
    #define ICE_STATIC_LIBS
    #include <IceUtil\IceUtil.h>

    Sample application with very basic thread test :-
    #include <iostream>
    #include <vector>
    using namespace std;
    //static linkage tested for Windows / VC2003 build
    #define ICE_STATIC_LIBS
    #include <IceUtil\IceUtil.h>
    class MyThread : public IceUtil::Thread {
    	virtual void run() {
    		IceUtil::ThreadControl self;
    		cout << "Thread " << << " started...\n";
    		for (int i=0; i < 5000000; ++i) ;
    		cout << "\nThread " << << " done...";
    int main(int argc, char *argv[])
    	vector<IceUtil::ThreadPtr> t;
    	vector<IceUtil::ThreadControl> tc;
    	const int maxThreads = 10;
    	for (int i=0; i < maxThreads; ++i) {
    		t.push_back(new MyThread);
    	for (int i=0; i < maxThreads; ++i) {
    	return 0;

    I hope that the other libraries are similar, but haven't delved into your plugin code (PluginManager or DynamicLibrary) and suspect these are fairly involved... For now I'd be happy with a basic commentary on whether the above approach is workable for IceUtil alone (knowing of course that you don't support static linkage officially).