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