[CMake] Use interface libraries for providing compile options and definitions

Craig Scott craig.scott at crascit.com
Thu Oct 3 18:29:49 EDT 2019


On Fri, Oct 4, 2019 at 2:27 AM Dustyn Blasig <dustyn at blasig.us> wrote:

> Hi All,
>
> I have been cleaning up our legacy CMake to use newer features (available
> in 3.12+) including trying to use target_...() functions nearly
> exclusively. As part of this, I was toying with cleaning up our use cases
> for adding compiler flags and similar definitions using real targets and
> target_link_libraries.
>
> For instance, as a simple example, let's say I wanted to add/provide a
> definition MY_FLAG, I could do something like...
>
> ```
> add_library(my_flag INTERFACE)
> target_compile_definitions(my_flag INTERFACE MY_FLAG=1)
>
> add_library(other_library SHARED ...)
> target_link_libraries(other_library ... *PRIVATE *my_flag)
>
> export/install rules
> ```
>
> I want this library to be private to my component, and it's only used
> under the PRIVATE banner. However, the issue I'm running into is with the
> install/export rules. I get an error similar to ...
>
> ```
> CMake Error: install(EXPORT "MY_PROJECT" ...) includes target
> "other_library" which requires target "my_flag" that is not in the export
> set.
> ```
>
> If my_flag is defined in my component, I can add it to the export set
> perhaps to workaround the issue, but in many cases, it would be coming from
> a helper script in another sub-project I'm fetching using FetchContent and
> don't want to expose the functionality via my export scripts.
>
> (1) Is it recommended to use interface libraries to clean up compile
> defintions, etc.
>

Personally, I don't typically use interface libraries to do this, I prefer
to list the requirements directly on the targets that they apply to. Some
people/projects may choose to collect a commonly used set of requirements
into an interface library, but one drawback with that is it creates the
temptation to lump a bunch of things together in that interface library
"for convenience", but end up with some targets having requirements applied
to them that aren't actually requirements for those targets at all. Used
appropriately, the technique can be helpful, but don't over-use it. ;)



> (2) Should it be possible to link privately such libraries and not have
> the export functionality complain?
>

>From a usage requirement point of view, the interface library shouldn't
need to be exported/installed because it is private. However, from a
linking point of view, a shared library still needs all other libraries it
links against for the linker to succeed at link time. Interface libraries
don't appear on the linker command line, so they shouldn't need to be
installed for linking to succeed, but I'm wondering if CMake's internal
logic isn't properly handling this. Can you open an issue in CMake's gitlab
<https://gitlab.kitware.com/cmake/cmake/issues> and attach a complete,
minimal example which reproduces the error (seems you're almost there with
the extracted commands above)?

-- 
Craig Scott
Melbourne, Australia
https://crascit.com

Get the hand-book for every CMake user: Professional CMake: A Practical
Guide <https://crascit.com/professional-cmake/>
Consulting services (CMake, C++, build/release processes):
https://crascit.com/services
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20191004/df9d391d/attachment-0001.html>


More information about the CMake mailing list