Use interface libraries for providing compile options and definitions

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Use interface libraries for providing compile options and definitions

Dustyn Blasig
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.
(2) Should it be possible to link privately such libraries and not have the export functionality complain?

Thanks!



--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Use interface libraries for providing compile options and definitions

Craig Scott-3


On Fri, Oct 4, 2019 at 2:27 AM Dustyn Blasig <[hidden email]> 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 and attach a complete, minimal example which reproduces the error (seems you're almost there with the extracted commands above)?
 
--
Craig Scott
Melbourne, Australia

Get the hand-book for every CMake user: Professional CMake: A Practical Guide
Consulting services (CMake, C++, build/release processes): https://crascit.com/services

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Use interface libraries for providing compile options and definitions

Dustyn Blasig
Thanks for the input. I will try to upload an example soon and upload an issue.

In the meantime, I think I'll go the route of providing a library of helper functions like `add_my_flag_target_definitions(other_library PRIVATE)` that any targets can call. It ends up being about the same amount of CMake code and doesn't run into the installation issues. If a client wants to bundle more of them together, they can simply create their own `add_my_superset_of_target_definitions(my_lib PRIVATE)` or something similar that calls all the other functions as needed.

On Thu, Oct 3, 2019 at 5:30 PM Craig Scott <[hidden email]> wrote:


On Fri, Oct 4, 2019 at 2:27 AM Dustyn Blasig <[hidden email]> 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 and attach a complete, minimal example which reproduces the error (seems you're almost there with the extracted commands above)?
 
--
Craig Scott
Melbourne, Australia

Get the hand-book for every CMake user: Professional CMake: A Practical Guide
Consulting services (CMake, C++, build/release processes): https://crascit.com/services

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake