[CMake] How can I compile and link modular code into a single DLL with MSVC?

Jason Heeris jason.heeris at gmail.com
Tue Jun 26 19:07:57 EDT 2018


This is a follow-on from "Linking object libraries into a Windows DLL in
3.12rc1"[1] - I figured since I'm reframing that question I should start a
new thread.

I have a project that has some common code and about a hundred modules. The
modules can have dependencies on each other (only ever as a directed
acyclic graph). What I want to do is, for any given module, compile it into
a single Windows DLL using MSVC (currently v19 under Visual Studio 2017).

This is already possible with existing build scripts, but these are
becoming unmaintainable. The existing scripts compile each individual
module into an .obj file and finally link them all into a DLL, as in:

cl.exe [args] common\common.c (creates common.obj)
cl.exe [args] modules\module1\module1.c (creates module1.obj)
...
cl.exe [args] modules\moduleN\ moduleN.c (creates moduleN.obj)

link.exe [args] common.obj module1.obj [...] moduleN.obj (creates
moduleN.dll)

(Not shown: the macros to create the declspec declaration that MSVC needs
to know what to export in the DLL. It's a type in moduleN and some
functions in common.)

I'm trying to figure out a way to do this with CMake that doesn't require
me to flatten out the entire dependency graph by hand. Each module has,
alongside it, a list of the other modules it *directly* depends on. These
are easy to put into a eg. target_link_libraries(...) call. But I can't
figure out how to get CMake to walk the whole dependency graph and pull
everything into the final link command.

Note that it doesn't have to be done with steps I describe above, if
there's another way to produce a single DLL I don't care how it happens.

What I've tried:

1. Making all the modules shared libs. This just produces a bunch of
separate DLLs for each module and common.

2. Chuck Atkins' post[2] suggesting separating usage requirements and
objects into different libraries. Since target objects don't propagate
using this method, it didn't help.

3. Now that 3.12rc1 is out, I tried using target_link_libraries() on the
object libraries themselves[1]. But as I found out from my previous post,
target objects don't
propagate this way either.

I'd appreciate any pointers. It seems like this is something that CMake is
designed to do, but I just can't figure out how. I have a very minimal
example (2 modules and common code) at https://gitlab.com/detly/cmake-dll-ex
which shows my attempt using object libraries, if that helps.

[1]
http://cmake.3232098.n2.nabble.com/Linking-object-libraries-into-a-Windows-DLL-in-3-12rc1-td7597756.html
[2]
http://cmake.3232098.n2.nabble.com/OBJECT-libraries-and-working-around-lake-of-target-link-libraries-tp7595795p7595830.html

Thanks,
Jason
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20180627/8d3903c5/attachment-0001.html>


More information about the CMake mailing list