# Module library is installed to LIBRARY instead of RUNTIME

**URL:** https://discourse.cmake.org/t/module-library-is-installed-to-library-instead-of-runtime/8388
**Category:** Usage
**Created:** [June 22, 2023, 10:21am UTC](https://discourse.cmake.org/t/module-library-is-installed-to-library-instead-of-runtime/8388 "2023-06-22T10:21:31Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![phbasler](https://discourse.cmake.org/user_avatar/discourse.cmake.org/phbasler/32/3546_2.png) [@phbasler](https://discourse.cmake.org/u/phbasler)
#### Post date: [June 22, 2023, 10:21am UTC](https://discourse.cmake.org/t/module-library-is-installed-to-library-instead-of-runtime/8388/1 "2023-06-22T10:21:31Z")

</div>

In my CMakeLists I have the following code segment

```auto
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](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?

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [June 22, 2023, 9:40pm UTC](https://discourse.cmake.org/t/module-library-is-installed-to-library-instead-of-runtime/8388/2 "2023-06-22T21:40:05Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![phbasler](https://discourse.cmake.org/user_avatar/discourse.cmake.org/phbasler/32/3546_2.png) [@phbasler](https://discourse.cmake.org/u/phbasler)
#### Post date: [June 24, 2023, 12:13pm UTC](https://discourse.cmake.org/t/module-library-is-installed-to-library-instead-of-runtime/8388/3 "2023-06-24T12:13:08Z")

</div>

Thanks for the explanation.

---

<div class="post-metadata">

### Author: ![BillyONeal](https://discourse.cmake.org/user_avatar/discourse.cmake.org/billyoneal/32/6033_2.png) [@BillyONeal](https://discourse.cmake.org/u/BillyONeal)
#### Post date: [February 23, 2026, 6:34pm UTC](https://discourse.cmake.org/t/module-library-is-installed-to-library-instead-of-runtime/8388/4 "2026-02-23T18:34:58Z")

</div>

> [@craig.scott](#):
>
> 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).

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

> [@craig.scott](#):
>
> Since a MODULE cannot be linked to, it doesn’t have that need, and `lib` is the more appropriate location for it.

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.

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [February 23, 2026, 6:56pm UTC](https://discourse.cmake.org/t/module-library-is-installed-to-library-instead-of-runtime/8388/5 "2026-02-23T18:56:22Z")

</div>

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`.

---

<div class="post-metadata">

### Author: ![BillyONeal](https://discourse.cmake.org/user_avatar/discourse.cmake.org/billyoneal/32/6033_2.png) [@BillyONeal](https://discourse.cmake.org/u/BillyONeal)
#### Post date: [February 23, 2026, 7:21pm UTC](https://discourse.cmake.org/t/module-library-is-installed-to-library-instead-of-runtime/8388/6 "2026-02-23T19:21:27Z")

</div>

> [@craig.scott](#):
>
> 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 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 `.so`s 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 🙂

> [@craig.scott](#):
>
> 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`.

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](https://learn.microsoft.com/windows/win32/dlls/dynamic-link-library-search-order#standard-search-order-for-unpackaged-apps)

I see contradictory things about where `.so`s 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](https://linux.die.net/man/3/dlopen) “The directories _/lib_ and _/usr/lib_ are searched (in that order).”)

---

<div class="post-metadata">

### Author: ![BillyONeal](https://discourse.cmake.org/user_avatar/discourse.cmake.org/billyoneal/32/6033_2.png) [@BillyONeal](https://discourse.cmake.org/u/BillyONeal)
#### Post date: [February 25, 2026, 8:12pm UTC](https://discourse.cmake.org/t/module-library-is-installed-to-library-instead-of-runtime/8388/7 "2026-02-25T20:12:57Z")

</div>

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