Module library is installed to LIBRARY instead of RUNTIME

In my CMakeLists I have the following code segment

add_library(myModule MODULE)
install(
  TARGETS myModule 
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
  )

add _library(mySharedLib SHARED)
install(
  TARGETS mySharedLib 
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
  )

If I now install these libraries, then mySharedLib is put to LIBRARY on linux and RUNTIME on windows (as expected by the documentation in https://cmake.org/cmake/help/latest/command/install.html#installing-targets

However the myModule dll is installed to LIBRARY on linux and windows.
Shouldn’t this also be installed to RUNTIME in windows since it is still a dll file?

A key thing that differentiates a MODULE from a SHARED library is that you cannot link to a MODULE library. A MODULE is intended to be loaded dynamically at run time. The only reason DLLs get put in bin is so that any other DLL or executable that links to it can find it at run time (assuming that DLL or executable is in the same directory). Since a MODULE cannot be linked to, it doesn’t have that need, and lib is the more appropriate location for it.

3 Likes

Thanks for the explanation.

Yes. dlopen and LoadLibrary need to be able to get to it at runtime.

Wait, what? lib is where linker inputs go, and you can’t link with one of these. Putting it in lib seems exactly backwards?
I understand this call was made forever ago and is likely frozen forever but I just want to make sure I understand.

I no longer recall the details of my reasoning at the time of my comment. Looking at it with fresh eyes today, I assume it was based around the idea that bin is conceptually “executables you run directly”, and that putting .dll files in there is just a pragmatic thing because Windows. That may well be a wrong view of things, but that’s my guess.

@BillyONeal Since you’ve re-raised it now though, I’d be interested if you can share details on contradictory conventions or standards that recommend putting libraries that cannot be linked to and only opened via dlopen() or equivalent somewhere other than lib.

That makes sense. In my brain “bin” is “things that go to the customers’ machine” and “lib” is “things that stay on the dev’s machine” but .sos kinda break this idea since they serve both purposes. Dynamic linking does seem to be one of those things for which people get a mental model about how it works on the platform they started on and have little understanding about everyone else and that’s certainly true in my case :slight_smile:

I don’t really have ‘standards’ to point to. Only that on Windows DLLs are ~always expected to be in the same place the .exe is because that’s where executable import tables and LoadLibrary look: step 7 of Dynamic-link library search order - Win32 apps | Microsoft Learn

I see contradictory things about where .sos should go; my naïve Windows brain wants them in bin because they get shipped to the user. But I usually see them in lib so I understand I’m probably mistaken about that. (Note that lib is explicitly where dlopen searches: https://linux.die.net/man/3/dlopen “The directories /lib and /usr/lib are searched (in that order).”)

Given where LoadLibrary and dlopen search it seems like bin is the correct location on Windows and lib is the correct location on POSIX.

1 Like