Porting CMSSW to Windows

 

Using Visual Studio 2005 (VC++ 8), I have been attempting to port CMSSW 1.3.0pre5
to Windows XP. I initially started with 1.2.0 but changed to the newer
version on advisement.

To make the port I amassed and where necessary rebuilt the following software packages:

1) ROOT v5.14 for Windows
2) POOL 2.5.0 for Windows, but built for VC++ 7
3) pthreads for Windows
4) xerces-c 2.7.0 for Windows
5) libsigc++ 2.0.17 for Windows
6) SEAL 1.9.2 for Windows, but built for VC++ 7
7) rx 1.5 for Windows, built for VC++ 7, but I converted it to VC++ 8
8) zlib 1.1.4 for Windows, built for VC++ 7
9) uuid 1.38 for Windows, built for VC++ 7
10) Boost 1.3.1 for Windows, rebuilt with VC++ 8, specifying Python
support and mixed pthreads and winthreads support
11) Python 2.5 for Windows

Using the CMSSW source tree from CVS, I created the following project categories:
a) DataFormats
b) Framework
c) MessageLogger
d) MessageService
e) Modules
f) ParameterSet
g) PluginManager
h) POOL
i) RootAutoLibraryLoader
j) SEAL
k) ServiceRegistry
l) Services
m) Utilities
n) uuid

and populated them with the appropriate source files.

For the compilation, I used the following preprocessor definitions:

_SCL_SECURE_NO_DEPRECATE 
_CRT_SECURE_NO_DEPRECATE 
BOOST_HAS_THREADS 
BOOST_HAS_PTHREADS 
BOOST_LIB_DIAGNOSTIC 
BOOST_PYTHON_NO_LIB 
NLOG 



(the first two avoid the VC++ 8 warnings about deprecated C++ features,
which got tiresome).

I had to make several changes to various header files to get some code to
compile. I commented each change, and the list of affected codes follows:
(this gives you an idea of the extent of code changes, but not what was
changed ... it is surprisingly little)
 

  J:\cmssw\DataFormats\Common\src\BranchDescription.cc(8)://JJB 
  J:\cmssw\DataFormats\Common\src\EDProduct.cc(8)://JJB 
  J:\cmssw\FWCore\Framework\src\CurrentProcessingContext.cc(5)://JJB 
  J:\cmssw\FWCore\Framework\src\EventProcessor.cc(11)://JJB 
  J:\cmssw\FWCore\Framework\src\EventProcessor.cc(1142):          //JJB 
  J:\cmssw\FWCore\Framework\src\EventProcessor.cc(1216):      //JJB 
  J:\cmssw\FWCore\Framework\src\EventSetupRecordIntervalFinder.cc(19)://JJB 
  J:\cmssw\FWCore\Framework\src\Group.cc(38):          //JJB && and || 
  J:\cmssw\FWCore\Framework\src\Group.cc(45):      //JJB && and ! 
  J:\cmssw\FWCore\Framework\src\IOVSyncValue.cc(24):    //JJB remove namespace eventsetup 
  J:\cmssw\FWCore\Framework\src\Schedule.cc(241):           //JJB 
  J:\cmssw\FWCore\MessageLogger\src\ELmap.cc(19)://JJB 
  J:\cmssw\FWCore\MessageLogger\src\ErrorObj.cc(50)://JJB 
  J:\cmssw\FWCore\MessageService\src\MessageLoggerScribe.cc(140):  //JJB 
  J:\cmssw\FWCore\MessageService\src\ELoutput.cc(79)://JJB 
  J:\cmssw\FWCore\RootAutoLibraryLoader\src\RootAutoLibraryLoader.cc(199):   //JJB this fuynction does not appear to be in Root 5.14 
  J:\cmssw\FWCoreWin\Helpers\seal\PluginManager\ModuleCache.cpp(415):    // JJB cast arg to unsigned long to remove ambiguity 
  J:\cmssw\FWCoreWin\Helpers\seal\PluginManager\PluginManager.cpp(82):    //JJB SealSearchPath 
  J:\cmssw\FWCoreWin\Helpers\seal\PluginManager\PluginManager.cpp(107)://JJB SealSearchPath 
  J:\cmssw\FWCoreWin\Helpers\seal\PluginManager\PluginManager.cpp(151)://JJB SealSearchPath 
  J:\cmssw\FWCoreWin\Helpers\seal\SealBase\SearchPath.cpp(10)://JJB global change to SealSearchPath 
  J:\cmssw\FWCore\ServiceRegistry\src\ServicesManager.cc(63):// JJB edm:: 
  J:\cmssw\FWCore\ServiceRegistry\src\ServicesManager.cc(183)://JJB edm:: 
  J:\cmssw\FWCore\Services\src\EnableFloatingPointExceptions.cc(88)://JJB add edm:: liberally 
  J:\cmssw\FWCore\Services\src\EnableFloatingPointExceptions.cc(184)://JJB edm:: 
  J:\cmssw\FWCore\Services\src\LockService.cc(24)://JJB edm:: 
  J:\cmssw\FWCore\Services\src\LockService.cc(54):// JJB edm:: liberally sprinkled 
  J:\cmssw\FWCore\Services\src\LockService.cc(85):// JJB edm:: 
  J:\cmssw\FWCore\Services\src\Memory.cc(27)://JJB 
  J:\cmssw\FWCore\Services\src\Profiling.cc(19)://JJB 
  J:\cmssw\FWCore\Services\src\Timing.cc(24)://JJB 
  J:\cmssw\FWCore\Services\src\Timing.cc(71):        //JJB 
  J:\cmssw\FWCore\Services\src\Timing.cc(120):      //JJB 
  J:\cmssw\FWCore\Services\src\Timing.cc(147):      //JJB 
  J:\cmssw\FWCore\Services\src\Tracer.cc(36)://JJB emd:: 
  J:\cmssw\FWCore\Services\src\Tracer.cc(118)://JJB edm:: 
  J:\cmssw\FWCore\Services\src\Tracer.cc(137)://JJB edm:: 
  J:\cmssw\FWCore\Utilities\src\UnixSignalHandlers.cc(4)://JJB 

 



I also created some missing functions and definitions that were required for Windows, e.g.  gettimeofday
and getrusage, and put them in a file called WinCMSSW.cpp.

In addition I created a WinCMSSW.h header file where I placed various $defines, structs and so forth,
together with an include of Windows.h. I then included this WinCMSSW.h file in various places in
the source.

Several of these "fixes" were kludges to get things working, rather than proper implementations:
I was more interested in getting to the point where I could run the code in the debugger and decide
what was important to have and what could be simply ignored for the Windows version.

After mostly successful compilation, I started linking everything together. This required the
correct library paths etc.. There were several unresolved externals, some of which
were (are) very difficult to understand due to the elaborate name dressing of C++.

After some work, and removal of problematic areas (such as SimpleProfiler, which as I
understand uses Unix process information, and therefore would require significant mods to
work on Windows), I was left with just 9 unresolved externals:
 

1>cmsRun.obj : error LNK2019: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl edm::pythonFileToConfigure(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?pythonFileToConfigure@edm@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABV23@@Z) referenced in function __catch$_main$0 
1>WorkerRegistry.obj : error LNK2019: unresolved external symbol "public: void __thiscall edm::Worker::connect(class sigc::signal<void,class edm::ModuleDescription const &,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil> &,class sigc::signal<void,class edm::ModuleDescription const &,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil> &,class sigc::signal<void,class edm::ModuleDescription const &,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil> &,class sigc::signal<void,class edm::ModuleDescription const &,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil> &,class sigc::signal<void,class edm::ModuleDescription const &,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil> &,class sigc::signal<void,class edm::ModuleDescription const &,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil> &)" (?connect@Worker@edm@@QAEXAAV?$signal@XABVModuleDescription@edm@@Unil@sigc@@U34@U34@U34@U34@U34@@sigc@@00000@Z) referenced in function "public: class edm::Worker * __thiscall edm::WorkerRegistry::getWorker(struct edm::WorkerParams const &)" (?getWorker@WorkerRegistry@edm@@QAEPAVWorker@2@ABUWorkerParams@2@@Z) 
1>WorkerRegistry.obj : error LNK2019: unresolved external symbol "public: class std::auto_ptr<class edm::Worker> __thiscall edm::Factory::makeWorker(struct edm::WorkerParams const &,class sigc::signal<void,class edm::ModuleDescription const &,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil> &,class sigc::signal<void,class edm::ModuleDescription const &,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil,struct sigc::nil> &)const " (?makeWorker@Factory@edm@@QBE?AV?$auto_ptr@VWorker@edm@@@std@@ABUWorkerParams@2@AAV?$signal@XABVModuleDescription@edm@@Unil@sigc@@U34@U34@U34@U34@U34@@sigc@@1@Z) referenced in function "public: class edm::Worker * __thiscall edm::WorkerRegistry::getWorker(struct edm::WorkerParams const &)" (?getWorker@WorkerRegistry@edm@@QAEPAVWorker@2@ABUWorkerParams@2@@Z) 
1>IncludeNode.obj : error LNK2019: unresolved external symbol "class boost::shared_ptr<class std::list<class boost::shared_ptr<class edm::pset::Node>,class std::allocator<class boost::shared_ptr<class edm::pset::Node> > > > __cdecl edm::pset::parse(char const *)" (?parse@pset@edm@@YA?AV?$shared_ptr@V?$list@V?$shared_ptr@VNode@pset@edm@@@boost@@V?$allocator@V?$shared_ptr@VNode@pset@edm@@@boost@@@std@@@std@@@boost@@PBD@Z) referenced in function "public: virtual void __thiscall edm::pset::IncludeNode::resolve(class std::list<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > &,class std::list<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > &)" (?resolve@IncludeNode@pset@edm@@UAEXAAV?$list@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@0@Z) 
1>MakersPSet.obj : error LNK2001: unresolved external symbol "class boost::shared_ptr<class std::list<class boost::shared_ptr<class edm::pset::Node>,class std::allocator<class boost::shared_ptr<class edm::pset::Node> > > > __cdecl edm::pset::parse(char const *)" (?parse@pset@edm@@YA?AV?$shared_ptr@V?$list@V?$shared_ptr@VNode@pset@edm@@@boost@@V?$allocator@V?$shared_ptr@VNode@pset@edm@@@boost@@@std@@@std@@@boost@@PBD@Z) 
1>ParseTree.obj : error LNK2001: unresolved external symbol "class boost::shared_ptr<class std::list<class boost::shared_ptr<class edm::pset::Node>,class std::allocator<class boost::shared_ptr<class edm::pset::Node> > > > __cdecl edm::pset::parse(char const *)" (?parse@pset@edm@@YA?AV?$shared_ptr@V?$list@V?$shared_ptr@VNode@pset@edm@@@boost@@V?$allocator@V?$shared_ptr@VNode@pset@edm@@@boost@@@std@@@std@@@boost@@PBD@Z) 
1>Profiling.obj : error LNK2019: unresolved external symbol "public: void __thiscall SimpleProfiler::start(void)" (?start@SimpleProfiler@@QAEXXZ) referenced in function "public: void __thiscall edm::service::SimpleProfiling::postBeginJob(void)" (?postBeginJob@SimpleProfiling@service@edm@@QAEXXZ) 
1>Profiling.obj : error LNK2019: unresolved external symbol "public: static class SimpleProfiler * __cdecl SimpleProfiler::instance(void)" (?instance@SimpleProfiler@@SAPAV1@XZ) referenced in function "public: void __thiscall edm::service::SimpleProfiling::postBeginJob(void)" (?postBeginJob@SimpleProfiling@service@edm@@QAEXXZ) 
1>Profiling.obj : error LNK2019: unresolved external symbol "public: void __thiscall SimpleProfiler::stop(void)" (?stop@SimpleProfiler@@QAEXXZ) referenced in function "public: void __thiscall edm::service::SimpleProfiling::postEndJob(void)" (?postEndJob@SimpleProfiling@service@edm@@QAEXXZ) 
1>J:\cmssw\FWCoreWin\Debug\FWCoreWin.exe : warning LNK4088: image being generated due to /FORCE option; image may not run 

 

I forced a build of the executable, and started stepping through in the debugger. I made some changes to cmsRun as I
went along, trying to understand if it was parsing my config file correctly (I got a simple one from Rick W.). There
were several problems, related to mismatching DLL versions. In particular, the C++ Runtime initialization of the
string processing was screwed up, so nothing with strings was making any sense. I fixed that by rebuilding some of
the SEAL software inside the project. But there are other, similar problems, I'm sure.

Right now, I can run down to the point where the new EventProcessor is instantiated, but then the runtime gets screwed up.
This is almost certainly a DLL mismatch problem.

My conclusion was that I really need SEAL and POOL built with VC++ 8 before
this is going to work ... and I do not know the schedule for when the IT people are going to do that.

My feeling is that, with POOL and SEAL (especially SEAL) built with VC++ 8, then we could have CMSSW working on Windows
without many more problems. Even better, if SEAL is to be removed, then we may be golden with a newer
version of CMSSW.