How to remove BASE_DIRS of FILE_SET from INTERFACE_INCLUDE_DIRECTORIES property

I’m using CMake 3.23.0 to enjoy the FILE_SET feature.

However, I don’t want to add BASE_DIRS of FILE_SET into INTERFACE_INCLUDE_DIRECTORIES property.

I can remove it from BUILD_INTERFACE, but how to remove from INSTALL_INTERFACE?

add_library(Math SHARED)
file(GLOB_RECURSE MathHeader ${MathRoot}/*.h ${MathRoot}/*.hpp)
target_sources(Math INTERFACE FILE_SET HEADERS FILES ${MathHeader})

# it's ok for me , to remove the BASE_DIRS from INTERFACE_INCLUDE_DIRECTORIES under this scope
# Remove the relative FILE_SET HEADERS BASE_DIRS from INTERFACE_INCLUDE_DIRECTORIES property
get_target_property(include_dirs Math INTERFACE_INCLUDE_DIRECTORIES)
list(REMOVE_ITEM include_dirs "$<BUILD_INTERFACE:${MathRoot}>")
set_target_properties(Math PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${include_dirs}")

# but, how to remove BASE_DIRS from INTERFACE_INCLUDE_DIRECTORIES property of EXPORT install target?

install(TARGETS Math
EXPORT MathTargets
RUNTIME DESTINATION bin # Executables & DLLs 
LIBRARY DESTINATION lib # Shared libraries, except DLLs
ARCHIVE DESTINATION lib # DLL import libraries & Static libraries .lib
FILE_SET HEADERS DESTINATION math/# FILE_SET
)

after installing Math target (install with EXPORT), I will get an automatically generated MathTargets.cmake file which contains this statements:

if(NOT CMAKE_VERSION VERSION_LESS "3.23.0")
  target_sources(Math
    INTERFACE
      FILE_SET "HEADERS"
      TYPE "HEADERS"
      BASE_DIRS "${_IMPORT_PREFIX}/xx/math"
      FILES "${_IMPORT_PREFIX}/xx/math/Common.h" "${_IMPORT_PREFIX}/xx/math/Constants.h" "${_IMPORT_PREFIX}/xx/math/Operator.h" 
  )
endif()

then linking Math will bring the BASE_DIRS into INTERFACE_INCLUDE_DIRECTORIES property.

How to remove BASE_DIRS from INTERFACE_INCLUDE_DIRECTORIES property?

What if you use PRIVATE instead of INTERFACE for the visibility of the header sources?

Thanks for your reply.

It works for me after changing INTERFACE to PRIVATE

Actually, the header files would not be installed if I set the FILE_SET as PRIVATE.

So, If I want to install the FILE_SET and not to add BASE_DIRS into INTERFACE_INCLUDE_DIRECTORIES.

How to achieve this goal?

Non-PRIVATE FILE_SETs will add their BASE_DIRS to the interface include directories. It’s how they work. I guess let’s back up: why do you not want this include interface?

Ok. Let me explain this by more details.

I have two folders like these:

projectRoot/math/extension/
Common.h
Math.h


projectRoot/solver/extension/
Common.h
Solver.h


Actually, if I want to explicitly include math/Common.h, I have to write like this:

#include "math/extension/Common.h"

Otherwise, it would bring ambiguity into my project if I have the “math/extension” and “solver/extension/” in INCLUDE_DIRECTORIES.

For example, the math library will be integrated by other host project, which contains it own Common.h.
Some of the host’s project might have this:

#include "Common.h"

If the Math library contains “math/extension” and “solver/extension/” in INCLUDE_DIRECTORIES.

Compiler will complain <#include “Common.h”: Common.h is ambiguous path. math/extension/Common.h or solver/extension/Common.h ?>

I think what you want here is the BASE_DIRS to be high up so that the file’s paths relative to it are math/common/Math.h and the like.

Thanks for your help.

After setting the BASE_DIR to be the higher folder path, the FILE_SET relative paths does NOT change.

It does NOT work for me.

Hi, could you solve this? I am facing the same problem

Posting a complete example that demonstrates the problem would help.