We have a complex code base with lots of smallish libraries generated by CMake. For internal use, we can just link against these libraries.
However, we also want to provide a public library for 3rd parties to use. The code in this library is implemented using many of our internal libraries. However, we only want to ship a single library. This is partly for convenience, and partly because we don’t want to expose more of our internal architecture than we need to.
Prior to moving to CMake, we had an archiving step that collapsed all the smaller libraries into a single exportable libraries. On some platforms, this was supported by the archiver (e.g. MacOS libtool). On others, we unpacked the sub-libraries and re-packed them into a single large library.
CMake doesn’t seem to have a mechanism to do this automatically. Post 3.12, one can achieve something similar with object libraries without a lot of pain. But if we switch all our internal libraries over to being object libraries, what are the hidden costs?
Alternatively, what would it take for CMake to support this behaviour directly?
Basic support would be to define a new target type ‘archive’. This would mostly function like a library, but target_link_libraries would re-pack the libraries into the archive (like happens post 3.12 when object libraries are added to a regular library) rather than add them to the link interface.
Rather than re-packing, the “archive” could treat all dependent libraries as if they were object libraries and grab their object files rather than the finished libraries. It’s possible to fudge this behaviour by using a CMake function to wrap add_library and switch between regular or object libraries. This might create issues if someone uses a feature that works on libraries but not object libraries which then breaks for archives - at least doing the switch manually rather than automatically makes it clear that someone unusual is happening.
More sophisticated archive behaviour would copy header files from PUBLIC dependencies into a new header directory. Given that adding headers (vs header paths) to projects is currently cosmetic, this could be managed in one of two ways:
- the archive target could list (relative?) paths to all headers to be included
- individual library targets could have some way of flagging headers as “to be exported” in the case of archives.
Handling header files might be stepping on CPack’s toes - a copy header files step is not needed to build the archive binary or link against it.