Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the use case for generator expression on target_include_directories?

I've seen in multiple places references to using generator expressions when defining include directories, so you can define different places for the includes during compilation and during installation. For example:

# Define headers for this library. PUBLIC headers are used for
# compiling the library, and will be added to consumers' build
# paths.
target_include_directories(lib PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
    PRIVATE src)

I'm building a library project and since I'm using standard paths (lib/ for the static library and include/ for the public headers), I was hoping to get away by setting CMAKE_INSTALL_PREFIX and using a simple install() call, such as:

set(CMAKE_INSTALL_PREFIX "${MY_INSTALL_DIR}")
install(TARGETS myLibrary ARCHIVE PUBLIC_HEADERS)

My expectations were that the DESTINATION would be the default for both, so I'm just telling CMake to install these kind of files. Of course it doesn't work and I need to explicitly set the destination for both libraries and header files.

So the question remains: what is the use case for the generator expressions at the beginning, if I don't seem to be able to use the INSTALL_INTERFACE anyway?


This is my sample CMakeLists.txt:

cmake_minimum_required(VERSION 3.12.1)
project(my_library C)

FILE(GLOB SOURCE_FILES src/*.c)
add_library(my_library ${SOURCE_FILES})
target_include_directories(my_library PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>)

set(OUTPUT_DIR "${CMAKE_BINARY_DIR}/output")
set(INSTALL_DIR "${OUTPUT_DIR}/my_library")
set(INSTALL_LIB_DIR "${INSTALL_DIR}/lib")
set(INSTALL_INC_DIR "${INSTALL_DIR}/include")
set(CMAKE_INSTALL_PREFIX "${INSTALL_DIR}")
install(TARGETS my_library ARCHIVE DESTINATION lib)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include" DESTINATION include)
# I was hoping I could do, after setting the headers with the INSTALL_INTERFACE generator expression
#install(TARGETS my_library ARCHIVE PUBLIC_HEADERS)
like image 774
Spidey Avatar asked Nov 06 '19 11:11

Spidey


1 Answers

Generator-like expressions $<BUILD_INTERFACE> and $<INSTALL_INTERFACE> are used by CMake for distinguishing things, different for the build tree and for the install tree.

When building the project itself, $<BUILD_INTERFACE> is used but $<INSTALL_INTERFACE> is not.

When creating an export file with the install(EXPORT) command, things listed in $<INSTALL_INTERFACE> will be included into it, but things in $<BUILD_INTERFACE> won't.

But the creation of an export file with the export command uses $<BUILD_INTERFACE>, but does not use $<INSTALL_INTERFACE>.

Other for differentiate build and install trees expressions $<BUILD_INTERFACE> and $<INSTALL_INTERFACE> are not used.

E.g. $<INSTALL_INTERFACE> does NOT affect the install(TARGETS .. PUBLIC_HEADERS) command.

like image 112
Tsyvarev Avatar answered Oct 17 '22 05:10

Tsyvarev