I have an imported shared library, A, which has several dependencies. I would like all of these dependencies to be listed correctly so that other executables/libraries which link with A can
use the TARGET_RUNTIME_DLLS:myExe generator to get a full runtime dll dependency list.
Most of these dependencies have both .dll and .lib files. These have no issue being SHARED IMPORTED targets and added to A’s INTERFACE_LINK_LIBRARIES list.
However, I have one runtime dependency, foo.dll, which does not have a corresponding .lib.
I can create a SHARED IMPORTED target, with IMPORTED_LOCATION_<RELEASE/DEBUG> set to the DLLs, however when I try to add it to A’s INTERFACE_LINK_LIBRARIES but this results in CMAKE complaining that the implib is missing.
I’m wondering what the correct approach is to make this work.
Thanks in advance.
EDIT: After a lot more reading, it seems that TARGET_RUNTIME_DLLS is not the right place to be looking for what should really be a PRIVATE dependency of A.
Not sure what the correct approach is supposed to be for copying private dependencies.
In theory you should be able to create any old (even empty) .lib file to stand in. It just needs to go into the place where it is expected by the linker as “supposed” import lib.
There is no fundamental difference between import and static libs on Windows with MSVC. You can even combine them into a hybrid form. So as long as the linnker is happy with the format, it should be fine.
Now, if the question is how to create an import library if you have none, you could try the gendef tool from MinGW to create a module definition file (.def) which can be used to create an import library.
Another method is to create a simple .c file with empty stubs mimicking the original functions, so that you can create an import library that way. The biggest problem you’ll run into if you attempt this is name mangling. The symbol names differed based on the calling convention on 32-bit. This is no longer an issue for 64-bit, though. For 64-bit there is basically just only one mangling scheme left. For 32-bit it differed for example between __cdecl and __stdcall. For __stdcall you would have to add the number of bytes expected via the stack past an @. E.g. function _Bla@4 would be a single-argument function. And for all intents and purposes it’s 4 bytes (= 32 bit) per additional argument.
At the PE loader and linker level these are just symbol names, though. So if they match, all is fine.
Thanks for the reply. Unfortunately I think the real issue is that I had a misunderstand of how TARGET_RUNTIME_DLLS worked. I thought it should be able to get all runtime dependencies, including all dependencies of linked libraries. Unfortunately, it really only works with PUBLIC dependencies.