"Jia L Wu" jwu@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?
Eric