Possible issue with BUILD_INTERFACE

Hello dear CMake community,

I’m very new to this forum, so I don’t really know if this is the right place to post such a message.

I may have accidentally found an issue in CMake, so I’ll post it here in order to discuss with more experienced user.

My setup is a x86_64 machine with Ubuntu 18.04, I reproduced the issue on both CMake 3.10.2 and 3.15.3.
It looks like when using several paths in the BUILD_INTERFACE macro, CMake is adding an extra absolute path (pointing to the root of the cmake application source directory).

Using this syntax, and installing & exporting the testlib target creates the faulty path:

target_include_directories(testlib
    PUBLIC
        $<BUILD_INTERFACE:
            ${CMAKE_SOURCE_DIR}/include1
            ${CMAKE_SOURCE_DIR}/include2
        >
        $<INSTALL_INTERFACE:include2>
    PRIVATE
        include
)

While the following does not:

target_include_directories(testlib
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include1>
        $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include2>
        $<INSTALL_INTERFACE:include2>
    PRIVATE
        include
)

It may also be me using the wrong syntax, but in any case I found that this extra path should not be added.
I created a repository on github to reproduce the issue with a minimal working example:


More information are available in the readme file.

Thank you in advance,
Kind regards,
Antonio

$<BUILD_INTERFACE:...> expects a list as argument. For that purpose, use a; as separator of the arguments or, better, use genex $<SEMICOLON>. So the correct expression is:

target_include_directories(testlib
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include1$<SEMICOLON>${CMAKE_SOURCE_DIR}/include2>
        $<INSTALL_INTERFACE:include2>
    PRIVATE
        include
)

Thank you for your response.
Any idea why this absolute path is inserted?

The problem is that you split the generator expression across multiple lines, which creates whitespace that CMake then interprets as a separator between arguments. What CMake sees is the following four separate arguments, not a single argument with a valid generator expression:

"$<BUILD_INTERFACE:"
"${CMAKE_SOURCE_DIR}/include1"
"${CMAKE_SOURCE_DIR}/include2"
">"

Unfortunately, CMake doesn’t warn when an argument looks like the beginning of a generator expression but is not in fact a valid generator expression (i.e. it is missing the closing >).

thank you very much for the clarifications!