# How to combine all dlls from subproject into one dll?

**URL:** https://discourse.cmake.org/t/how-to-combine-all-dlls-from-subproject-into-one-dll/7235
**Category:** Usage
**Created:** [January 11, 2023, 2:47pm UTC](https://discourse.cmake.org/t/how-to-combine-all-dlls-from-subproject-into-one-dll/7235 "2023-01-11T14:47:44Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![zhang-qiang-github](https://discourse.cmake.org/user_avatar/discourse.cmake.org/zhang-qiang-github/32/1913_2.png) [@zhang-qiang-github](https://discourse.cmake.org/u/zhang-qiang-github)
#### Post date: [January 11, 2023, 2:47pm UTC](https://discourse.cmake.org/t/how-to-combine-all-dlls-from-subproject-into-one-dll/7235/1 "2023-01-11T14:47:44Z")

</div>

Now, I have several subprojects, which will export dll files. Let’s say, I will have 10 dlls.

Is there any method to combine all 10 dll files into one dll file?

In `opencv`, if we set `BUILD_opencv_world` to `on`, it will finally export one dll file. If the `BUILD_opencv_world` is `off`, the `opencv` project would export many dll files.

How can I combine the 10 dll files into one dll file?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [January 11, 2023, 3:07pm UTC](https://discourse.cmake.org/t/how-to-combine-all-dlls-from-subproject-into-one-dll/7235/2 "2023-01-11T15:07:37Z")

</div>

This isn’t generally possible. Windows executables have different calls for symbols in the library from those outside the library. Recompilation is the only reliable way.

---

<div class="post-metadata">

### Author: ![zhang-qiang-github](https://discourse.cmake.org/user_avatar/discourse.cmake.org/zhang-qiang-github/32/1913_2.png) [@zhang-qiang-github](https://discourse.cmake.org/u/zhang-qiang-github)
#### Post date: [January 12, 2023, 1:31am UTC](https://discourse.cmake.org/t/how-to-combine-all-dlls-from-subproject-into-one-dll/7235/3 "2023-01-12T01:31:16Z")

</div>

I can recompile it. After recompiling, how can I combine exported many dll files into one dll file?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [January 12, 2023, 6:36pm UTC](https://discourse.cmake.org/t/how-to-combine-all-dlls-from-subproject-into-one-dll/7235/4 "2023-01-12T18:36:22Z")

</div>

The project needs to support it. `BUILD_opencv_world=ON` is what I’d do.

---

<div class="post-metadata">

### Author: ![zhang-qiang-github](https://discourse.cmake.org/user_avatar/discourse.cmake.org/zhang-qiang-github/32/1913_2.png) [@zhang-qiang-github](https://discourse.cmake.org/u/zhang-qiang-github)
#### Post date: [January 13, 2023, 12:22am UTC](https://discourse.cmake.org/t/how-to-combine-all-dlls-from-subproject-into-one-dll/7235/5 "2023-01-13T00:22:21Z")

</div>

Do you mean that I need to `set(BUILD_opencv_world ON)` in my `CMakeLists.txt`? Why it is `"opencv"_word`? Should I modify it as my project name? For example `set(BUILD_helloworld_world ON)`. Can `CMake` recognize the `BUILD_helloworld_world ` variable?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [January 13, 2023, 1:54am UTC](https://discourse.cmake.org/t/how-to-combine-all-dlls-from-subproject-into-one-dll/7235/6 "2023-01-13T01:54:20Z")

</div>

> [@zhang-qiang-github](#):
>
> Why it is `"opencv"_word`?

You mentioned the variable in the original post. Or was this a hypothetical switch you _would_ use to do this? OpenCV needs to support this natively as an option; it’s not trivial to “just combine DLLs”, especially on Windows.

---

<div class="post-metadata">

### Author: ![scottaronbloom](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/b4bc9f/32.png) [@scottaronbloom](https://discourse.cmake.org/u/scottaronbloom)
#### Post date: [January 17, 2023, 12:26am UTC](https://discourse.cmake.org/t/how-to-combine-all-dlls-from-subproject-into-one-dll/7235/7 "2023-01-17T00:26:45Z")

</div>

When opencv builds with `BUILD_opencv_world` set to on, its basically using a single link line to generate the shared library vs multiple link lines.

The easiest way to accomplish what you are doing, would be to follow the same pattern.

Typically, the easiest way to generate a DLL on windows, is you create a an “EXPORT/IMPORT” macro that precedes each symbol being exported

When your library generation is being compiled and reads the header for the library function, the macro is set to declspec(export), when the executable or another library is reading the header its set to declspec(import)

You likely have multiple of these macros, one for each shared library. You will have to modify the macro logic so its defined as external for the logic of “Am I building the unified DLL or my single DLL then export, otherwise import”

Then from a CMake POV, you need to do a couple of things when this flag is turned on.

- set the compiler flag
- Generate static libraries where previously shared libraries were created
- Create a new target shared library, that linked in all the static libraries

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [January 17, 2023, 12:51am UTC](https://discourse.cmake.org/t/how-to-combine-all-dlls-from-subproject-into-one-dll/7235/8 "2023-01-17T00:51:42Z")

</div>

> [@scottaronbloom](#):
>
> You likely have multiple of these macros, one for each shared library. You will have to modify the macro logic so its defined as external for the logic of “Am I building the unified DLL or my single DLL then export, otherwise import”

VTK does this with its “kits” logic:

[https://gitlab.kitware.com/vtk/vtk/-/blob/7993258010c5c5193b90471b50412ec816f02c30/CMake/vtkModule.cmake#L3775-3794](https://gitlab.kitware.com/vtk/vtk/-/blob/7993258010c5c5193b90471b50412ec816f02c30/CMake/vtkModule.cmake#L3775-3794)

---

<div class="post-metadata">

### Author: ![zhang-qiang-github](https://discourse.cmake.org/user_avatar/discourse.cmake.org/zhang-qiang-github/32/1913_2.png) [@zhang-qiang-github](https://discourse.cmake.org/u/zhang-qiang-github)
#### Post date: [January 17, 2023, 3:36am UTC](https://discourse.cmake.org/t/how-to-combine-all-dlls-from-subproject-into-one-dll/7235/9 "2023-01-17T03:36:36Z")

</div>

> [@scottaronbloom](#):
>
> You will have to modify the macro logic so its defined as external for the logic of “Am I building the unified DLL or my single DLL then export, otherwise import”

If so, how to define the name of the single dll file?

If there are multiple dll files, the name of each dll file is the name of project.

If there is only one dll file, what’s the name of this single dll file?

---

<div class="post-metadata">

### Author: ![scottaronbloom](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/b4bc9f/32.png) [@scottaronbloom](https://discourse.cmake.org/u/scottaronbloom)
#### Post date: [January 17, 2023, 3:52am UTC](https://discourse.cmake.org/t/how-to-combine-all-dlls-from-subproject-into-one-dll/7235/10 "2023-01-17T03:52:13Z")

</div>

You need to create a new project with the unified name
