Some background. I was upgrading a project to use FILE_SET hopefully to simplify things.
I have attached an example project. I build into an out of source build directory and generate the Visual Studio solution using cmake -G "Visual Studio 17 2022" ../src
Note I can make all this work using some target_include_directories and the like but I was really trying to use FILE_SET as much as possible to learn stuff about it. This might just be pushing FILE_SET usage beyond what it is intended for?
So there is one project HelloWorld that lives in a sub directory HelloWorld The project uses
target_sources(HelloWorld PUBLIC
FILE_SET HEADERS
BASE_DIRS
${CMAKE_SOURCE_DIR}
FILES HelloWorld.h)
for it’s one header. This all works well.
On install the HelloWorld.h header if install in include/HelloWorld/HelloWorld.h which is what I expect. This is using
install(
TARGETS HelloWorld
EXPORT HelloWorldExport
FILE_SET HEADERS
)
The HelloWorld CMake also generates an export header using
generate_export_header(HelloWorld)
The helloworld_export.h is generated in the ${CMAKE_CURRENT_BINARY_DIR} as expected.
Now in HelloWorld.cpp this header is included as
#include "helloworld_export.h"
Using the double quotes in the #include here is the way I have seen in every project I have worked on. So to find this file I need ${CMAKE_CURRENT_BINARY_DIR} in the include path so I can do the following to achieve this
target_sources(HelloWorld PUBLIC
FILE_SET generated_export_headers
TYPE HEADERS
${CMAKE_CURRENT_BINARY_DIR}
FILES ${CMAKE_CURRENT_BINARY_DIR}/helloworld_export.h)
So I add this file set to the install to get
install(
TARGETS HelloWorld
EXPORT HelloWorldExport
FILE_SET HEADERS
FILE_SET generated_export_headers
)
However the install is then
1>-- Up-to-date: .../install/include/HelloWorld/HelloWorld.h
1>-- Up-to-date: .../install/include/helloworld_export.h
However this is not what I want. I want the helloworld_export.h to be in the HelloWorld directory beside the HelloWorld.h file. So the install path I want includes the HelloWorld directory. This can be done using the following
target_sources(HelloWorld PUBLIC
FILE_SET generated_export_headers
TYPE HEADERS
BASE_DIRS ${CMAKE_BINARY_DIR}
FILES ${CMAKE_CURRENT_BINARY_DIR}/helloworld_export.h)
This does what I want on install
1>-- Up-to-date: .../install/include/HelloWorld/HelloWorld.h
1>-- Up-to-date: .../install/include/HelloWorld/helloworld_export.h
However that makes the build fail as it can not longer find helloworld_export.h. So I thought I would use a different BASE_DIR for build and install like so
target_sources(HelloWorld PUBLIC
FILE_SET generated_export_headers
TYPE HEADERS
BASE_DIRS $<BUILD_LOCAL_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}> $<INSTALL_INTERFACE:${CMAKE_BINARY_DIR}>
FILES ${CMAKE_CURRENT_BINARY_DIR}/helloworld_export.h)
However that still installs
1>-- Up-to-date: .../install/include/HelloWorld/HelloWorld.h
1>-- Up-to-date: .../install/include/helloworld_export.h
So it seems like the generator expressions aren’t working like the BUILD_LOCAL_INTERFACE still triggers in an install command.
Example.zip (1.8 KB)