Binaries Backward Compatibility
It's sometimes difficult to deal with backward compatibility.
VC++
One example is Microsoft, which have new MSVCRTXX.DLL with each Visual Studio version it ships. And you can't easily downgrade to an old one ! Since some people are still using a machine on which the .Net Runtime is not installed, I'm still building NekoVM with the good-old-msvcrt60.lib which was included in my Visual C++ 6.0.
In order to do that, you have to :
- get your hands on this old .lib file
- ignore MSVCRT from the libraries, and manually link your own .lib
In some cases, this might cause some trouble. For example, it cannot find _ftol2 (float-to-long) which was only included in more recent MSVCRT (and the new compiler is using it of course !). By defining the following functions you can get around with it :
extern "C" { long _ftol( double f ); long _ftol2( double f) { return _ftol(f); }; }
You'll also have to disable some stuff about exception checking, but that's not hard to find...
GCC
But Microsoft is not the only one to come with problems of backward-compatible binaries. When compiling libneko.so with GCC 4.2, and then running the nm libneko.so | grep GLIBC
command on it to check the imported symbols, you will notice the following :
U __stack_chk@@GLIBC_2.4
This is the only one dependency with GLIB 2.4 , which is also not installed on some old systems. The good news is that GCC has an option to disable this dependency, which is called -fno-stack-protector
. Sadly, when compiling some executables, you don't want (and sometimes can't) add this parameter to all the C files that are compiled (that would be a mess).
So how do you globally change the GCC configuration for your system ? Here's the steps :
- dump the GCC spec file to a local file, by using
gcc -dumpspecs >specs
- edit the
specs
file and remove the place where-fstack-protector
is defined - put that updated
specs
file in the GCC config directory (on Ubuntu it's on/usr/lib/gcc/[arch]/[version]/
) - et voilà ! you can rebuild your code which will work with GLIBC 2.3
Conclusion : Binary backward compatibly is hard to obtain, and it takes hours to find how to configure it. And when you finally know how to do it, you blog about it, to help other people with the same problem, but also to remember how you did it the next time you reinstall your system !
Here's my idiosyncratic solution to the VC++ problem, which allows me to use the latest Microsoft compiler and Windows SDK while still linking against msvcrt.dll.
I do this with Visual Studio 2008 Professional, the Windows SDK version 6.0A (bundled with VS2008), and the Windows Driver Kit version 6.0. My .cmd file for setting the appropriate environment variables is below. The msvcrt.lib import library in the Windows Driver Kit references msvcrt.dll. The major caveat is that you have to include "msvcrt_win2000.obj" on the command line, or the resulting binary will only run on Windows Vista and later. I was unable to devise a way around this. Still, this is the best solution I've found.
vc9wdkenv32.cmd:
@echo off
set PATH=C:\Program Files\Microsoft VIsual Studio 9.0\VC\bin;C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE;C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools;C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin;%PATH%
set include=C:\winddk\6000\inc\crt;C:\winddk\6000\inc\api\crt\stl70;C:\Program Files\Microsoft Visual Studio 9.0\VC\include;C:\winddk\6000\inc\atl30;C:\Program Files\Microsoft SDKs\Windows\v6.0A\include
set lib=C:\winddk\6000\lib\crt\i386;C:\winddk\6000\lib\atl\i386;C:\Program Files\Microsoft SDKs\Windows\v6.0A\lib;C:\winddk\6000\lib\w2k\i386;C:\Program Files\Microsoft Visual Studio 9.0\VC\lib