How to port c++ program to linux using winelib
efrias at syncad.com
Mon Oct 18 09:30:02 CDT 2004
"Jia L Wu" <jwu at cc.helsinki.fi> wrote:
> It seems that I have to write a spec file for each dll to import(and
> export) functions provide by other dlls. However, since they all written
> in c++ and what need to be imported can either be class or class method,
> and parameters can be class either. SO I don't know how to handle this in
> spec file. Beside each dll file exports many functions or classes. It
> would be tedious to write a lengthy spec file manually.
> My question is that if it is possible that linking is not invoked during
> shared library generation under wine (but during the runtime)? How should
> I do it?
I don't have an answer, just tagging along here. I'm curious what other
people have come up with, both for the long-term solutions and the best way
to get it working today.
I'm working on a large C++ application that is divided into many shared
objects. We are currently using a version of wine that is about a year old.
With that version, we were able to get C++ shared libraries to link together
by bypassing wine's DLL mechanism for all of the C++ symbols -- we just let
the native linux loader resolve the C++ symbols. We just created empty
.spec files for all of the C++ DLLs we wrote. When we called winebuild to
generate the .spec.c file for each DLL, we would only tell winebuild that we
were linking against DLLs that were part of wine (kernel32, user32, etc).
Then when we did the actual linking for the DLL we were building, we would
pass in the names of the other DLLs we depend on the typical way
(-lour_library.dll), and the native linker would resolve those symbols for
us. This worked very well for us. I suspect there are a few things that
this would have broken, like calling GetProcAddress on one of our C++
symbols, but that isn't a feature we ever used.
We got a rude suprise when we tried to update to a current version of wine a
month or two ago. The DLL loading mechanism had changed during that span,
and hack we were using would no longer work. It looks like the current
version of wine won't allow you to link to a wine DLL with the native
linker. It expects all linking between wine DLLs to be done through
winebuild, and it gets confused when a DLL gets loaded (by the shared
loader) that wine didn't explicitly load. We haven't yet figured out what
to do about this.
We could try to modify wine's loading mechanism to allow the kind of hackery
we were doing before, but I don't know much about this part of wine and I'm
not sure what the consequences of loding DLLs out-of-order are. I guess the
other option is to generate .spec files for all of our DLLs, which is an
option that doesn't really appeal to me either. It'd be pretty easy to
write a script that will massage the output of nm(1) to generate a .spec
file, but if you do that you're going to be exporting every symbol, most of
which will probably be unused.
I seem to recall that there are experimental(?) modifications to gcc and
binutils that understand declspec(__dllexport)-type annotations. I think
this was part of mingw. IIRC, gcc would somehow mark the exported symbols
in the object files, and a separate utility would scan the object files and
create a .def file with all of the exported symbols. I'm not sure this
stuff even compiles on linux.
Does anyone have a solution they're happy with?
More information about the wine-devel