Hello Bruno,
Sorry for the delayed answer (vacations are the reason). I'll inline
my answers with your previous posting, as enough time has passed not
to remember what the details were.
----- Original Message ----- From: "Bruno Haible" <address@hidden>
To: "Milan Gornik" <address@hidden>;
<address@hidden>
Sent: Saturday, December 29, 2007 5:43 PM
Subject: Re: [bug-gnu-libiconv] libiconv 1.11.1 - MS VS 2005 and manifest
files
Hello Milan,
Milan Gornik wrote:
I am using libiconv 1.11.1 with Microsoft Visual Studio 2005 and I have
encountered one problem. Iconv builds fine and works fine until
binaries
are
distributed to machine without development environment. On such
machine,
binary built to use libiconv will fail to execute, as it can't bind
with
CRT
runtime (MSVCR80.dll). Application will stop with dialogue explaining
that
MSVCR80.dll could not be found.
The same problem is mentioned in libiconv-1.11.1/README.woe32, for MSVC
7.0
and the msvcr70.dll library.
Yes, indeed. This is properly documented. However, I tried to find
simple way to make libiconv work with Visual Studio 2005, from
building phase to deployment. So, the idea is to build libiconv with
VS 2005, to make it depend only on VS 2005 libraries and to make it
deployable. Also, I wanted to make requirements of such deployment the
same as all VS 2005 applications are having.
A possible fix is to get back to MSVC 6.0.
This happens because OS seeks for
executable's manifest file to determine which CRT to use with the
executable. In this case, no manifest files are available. When Iconv
library is built, manifest files are generated for every output file
(EXE
and DLL), but these files are left behind (in source folders). They are
not
installed to output folder. As makefiles are designed for Visual Studio
98
(v6), there are no special options in makefiles regarding manifest
files.
Linker generates these files by default.
I believe that best option would be to integrate manifests with their
appropriate output files (EXE files and DLL files). This makes minimal
impact on how Iconv is built (no additional files, installation
phase is
not
affected, build phase is extended with manifest file integration). The
result will be that every DLL and EXE will contain embedded manifest
(and
will run correctly on machine without development environment). Small
modification to makefiles is needed to achieve this. I followed
recommendations in MSDN to do this. I attached diff files to this
message.
This looks like a hack to me. You build a library for use with
MSVCR80.DLL
and then relabel it to work with MSVCRT.DLL? There is no guarantee that
this
will work. Surely MSVCR80.DLL contains more symbols than the older DLL.
What happens if one of the symbols needed by iconv.dll is present in
MSVCR80.DLL but not in MSVCRT.DLL? The application that needs iconv will
certainly crash. Since we don't have a 100% test coverage of libiconv,
you cannot know about this case before it actually happens on the
deployment
machine.
My explanation wasn't really good, so I'll try to explain it again. If
I'm not wrong, libiconv doesn't explicitly require any CRT library. As
I presume, it just uses C routines, and it depends on building
environment which actual CRT library will be used with libiconv
executables. When libiconv is built with Visual Studio 98 (Visual C
6), libiconv will depend on MSVCRT.DLL. Of course, it can be bound to
static library, but in this posting, I'll consider only dynamically
bound CRT. When libiconv is built with Visual Studio 2005, libiconv
will depend on MSVCR80.dll. Maybe the confusion came from the name of
Microsoft's CRT library. First one doesn't have version in its name,
while the second has the version of C compiler in its name. I guess
they wanted to introduce backward-compatible CRT when they
designed old Visual Studio (98) and dropped the idea later.
Microsoft CRT libraries are now available only through MS
Redistributable packages. MSDN has download site for these packages.
These packages contain CRT libraries, for different architectures, in
different versions and releases.
When dll or exe is built with Microsoft Visual Studio 2005 it will
have dependency to very specific version of CRT library (even to a
build number!). There is no compatibility between different versions
of CRTs. For example, when library is built with VS 2005 with Service
Pack 1 installed, it will require identical CRTs to run on deployment
machine. If deployment machine has CRTs from VS 2005 (without Service
Pack) executable will refuse to run. Microsoft deploys its CRTs in
Redistributable packages, and there are versions available for every
corresponding Visual Studio. So, it is required that exact version of
CRT that was used to build executable also exist on the deployment
machine. This is what Manifest files are used for. Every VS 2005
binary should have its manifest file. This file is a small XML
specification which declares exact version of system libraries used
with the binary. CRT is one of these libraries; others are MFC, ATL...
What I tried to address in my previous posting wasn't how to make
library build with VS 2005 to run on machine that doesn't has required
CRTs. I only tried to address the question on how to resolve the
situation with Manifest files (more on this later).
This is what my intentions were: Build libiconv with VS 2005, thus
making it require VS 2005 CRT - MSVCR80.dll. Then, I'm assuming that
deployment machine has right version of MS Redistributable installed
(it is standard requirement of all VS 2005 applications). Of course,
the version of CRTs with which libiconv is built must be the same as
the version of libs in Redistributable. After that, libiconv can work
on deployment machine, but its Manifest file must also be present. As
I mentioned before, it is used to connect binaries to their
dependencies. When libiconv is built on VS 2005, linker will generate
appropriate manifest file (it does so by default). That's what already
happens during building of libiconv. However, these manifest files
will be left behind in folders used to build libiconv (as they are not
installed to output folder with the binaries) and thus it will not be
possible to actually deploy and use libiconv.
My posting was on how to integrate manifest files with dll's. That
way, when libiconv is deployed, it won't require manifests to be
deployed separately. So, this procedure doesn't change dependencies of
libiconv. It only makes it deployable by integrating dependency
information with libiconv binaries.
I also believe this doesn't collide with MS licenses. The difference
between the deployment now (VS 2005) and before (VS 98) is that CRT
dll is not deployed with the binaries. Instead, it should be installed
using appropriate MS Redistributable package, which is available on
Microsoft site.
Best regards,
Milan Gornik
P.S. Merry Christmas and happy New Year!