On Fri, 2017-10-27 at 12:22 -0700, Wesley Smith wrote:
> Boost's CMAKE page (http://bcm.readthedocs.io/en/latest/src/Building.html) 
> says:
> 
> So this will build the library named boost_filesystem, however, we need to
> supply the dependencies to boost_filesystem and add the include directories.
> To add the include directory we use target_include_directories. For this, we
> tell cmake to use local include directory, but since this is only valid
> during build and not after installation, we use the BUILD_INTERFACE
> generator expression so that cmake will only use it during build and not
> installation:
> 
> target_include_directories(boost_filesystem PUBLIC
>     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
> )
> 
> 
> Is is necessary to use a BUILD_INTERFACE here?  Couldn't you use
> PUBLIC/PRIVATE/INTERFACE to achieve the same effect?  What are the use cases
> over for BUILD_INTERFACE that setting include dirs as
> PUBLIC/PRIVATE/INTERFACE doesn't cover?

You don't need `BUILD_INTERFACE` if it is set to `PRIVATE`, as none of the
downstream users will use the include. However, when using `PUBLIC` or
`INTERFACE` you will need `BUILD_INTERFACE`, and in the example above it using
`PUBLIC`.

This is because there are two types of consumers using the target. One is a
target within the build. This will use the include directory from the
source(or build) directory. The `BUILD_INTERFACE` ensures that this is only
used for this type of consumer.

The other type of consumer is the what is used after installation. In this
case the include directory is different and most likely points to the
directory in installation directory like `${CMAKE_INSTALL_PREFIX}/include`.
The `INSTALL_INTERFACE` ensures that this is only used for this type of
consumer.

So for this case, you setup the includes something like this:

target_include_directories(boost_filesystem PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
)

This will ensure that each type of consumer get the correct include directory.
Ultimately, you don't want the user to add an include to a local source
directory, as this could have surprising side effect. Fortunately, cmake
ensures that this won't happen either, by producing an error if the
installations include paths that point to directories in the source or build
directory.

At the same token, you also don't want the build to point to the installation
include as well as this may include headers you don't want to use.

Finally, in the example above it didn't use the `INSTALL_PREFIX`. This is
because the install sets it correctly when using the `INCLUDES DESTINATION`
statement:

install(TARGETS boost_filesystem EXPORT boost_filesystem-targets
    RUNTIME DESTINATION bin
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    INCLUDES DESTINATION include
)

Paul
-- 

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:
http://public.kitware.com/mailman/listinfo/cmake

Reply via email to