Having many DLLs is not necessarily bad. Historically, DLLs have two primary trade-offs:
They require more time when loading. When required they must be loaded into memory and locations mapped out to allow jumping into function locations. If a DLL is not preloaded at program start, this might mean pauses while a program is loading.
They require less space, assuming DLLs are centrally located and reused in multiple programs.
However, modern hardware nullifies these attributes. Modern computers are so fast that unless you literally have hundreds of DLLs to load, the delay will be barely noticeable, if at all. Modern storage capacities are through the roof, and the extra space required by not sharing libraries is generally not noticed. My Android phone has two orders of magnitude more storage than my first desktop computer (and some of the old timers around here can outdo that).
If you are still concerned about this, consider static linking your libraries into your program executable. Do not simply copy the source code.
Static linking has some potential advantages:
- You never need be concerned about using the wrong version of a DLL.
- If you can shrink your program down to a single file it becomes easier to make portable. Note that this is neither necessary nor sufficient to make an app portable, it only makes the job easier. This may or may not be a concern.
- Modern linkers do a pretty good job removing dead code when static linking. For example, I have seen DLLs in the tens of megabytes. Toolkits such as Qt can be that large. If you are only using a small portion of the toolkit, consider static linking instead. The linker can elide all of the unused (dead) code, bringing the combined size of your code and the library code to something much more reasonable.
- Saving the best for last: some compilers support whole-program optimizations. This can potentially increase the run-time speed of your program, typically at a severe cost during compile time.
There is one disadvantage to static linking a large amount of code into the primary executable:
- The initial load time is longer. The entire executable must normally be loaded into memory, globals initialized, entry logic run, etc. before
main() can be called. This could be a lengthy delay before control passes to your program. Some larger programs (e.g. MS Office) get around this by offloading much of the program into DLLs which are loaded after
main() is called: this allows the opportunity to display a splash (loading) screen. If you static link everything, you cannot do this.
This might not even be an issue for you. Most programs are not large enough to require a loading screen. Besides, modern hardware is lightning fast compared to the dark ages when this was a truly serious decision.
It is critical that you do not simply copy the source code:
- Most, if not all, OSI-approved licenses will allow you to link code units. That is part of what makes "open source" to be "open."
- Linking code reduces coupling compared to copying code. While the code references are the same, it is easier to upgrade to a newer library version if you can simply drop in a new static library and link away.
- Depending on the compatibility of the licenses used in your code and each library, you might not be allowed to copy the code in and still be in compliance with the licenses. That may create a derivative or combined work, which opens several cans of worms (one can for each combination of licenses). That is a headache you do not want. Further discussion on the topic is dangerously close to legal advice, so I recommend simply avoiding the whole issue and going the linking route after you read the relevant licenses.