CMake target_include_directories doesn't export to compile_commands.json when using CUDA

I am trying to use CMake to build a CUDA project. However, when I use add_library followed by target_include_directories, the relevant commands are not updated in the compile_commands.json file.
Screenshot 2024-02-12 at 21.45.05
The structure of the project is shown here. There are three CMakeLists.txt; one in Euler_CUDA, one in src and one in solver. In sequence, the CMakeLists are the following:

cmake_minimum_required(VERSION 3.19)

project(CUDA_Practice)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wall -Werror -pedantic")
enable_language(CUDA)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)

add_subdirectory(src)

execute_process(
    COMMAND ${CMAKE_COMMAND} -E create_symlink
        ${CMAKE_BINARY_DIR}/compile_commands.json
        ${CMAKE_SOURCE_DIR}/compile_commands.json
)
add_subdirectory(solver)

find_package(PkgConfig REQUIRED)
pkg_search_module(LIBCONFIG++ REQUIRED libconfig++)

add_executable(main main.cu)
target_include_directories(main PUBLIC ${LIBCONGIG++_INCLUDE_DIRS})

target_link_libraries(main PUBLIC solver_lib)
target_link_libraries(main PUBLIC ${LIBCONFIG++_LINK_LIBRARES})
add_library(solver_lib STATIC solver.cu equationOfState.cu)

target_include_directories(solver_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

And the compile_commands.json file which is output looks like the following

[
{
  "directory": "/home/raid/sy451/Euler_CUDA/build/src",
  "command": "/lsc/opt/cuda-11.7/bin/nvcc -forward-unknown-to-host-compiler  --options-file CMakeFiles/main.dir/includes_CUDA.rsp -std=c++17 \"--generate-code=arch=compute_52,code=[compute_52,sm_52]\" -x cu -c /home/raid/sy451/Euler_CUDA/src/main.cu -o CMakeFiles/main.dir/main.cu.o",
  "file": "/home/raid/sy451/Euler_CUDA/src/main.cu",
  "output": "src/CMakeFiles/main.dir/main.cu.o"
},
{
  "directory": "/home/raid/sy451/Euler_CUDA/build/src/solver",
  "command": "/lsc/opt/cuda-11.7/bin/nvcc -forward-unknown-to-host-compiler  --options-file CMakeFiles/solver_lib.dir/includes_CUDA.rsp -std=c++17 \"--generate-code=arch=compute_52,code=[compute_52,sm_52]\" -x cu -c /home/raid/sy451/Euler_CUDA/src/solver/solver.cu -o CMakeFiles/solver_lib.dir/solver.cu.o",
  "file": "/home/raid/sy451/Euler_CUDA/src/solver/solver.cu",
  "output": "src/solver/CMakeFiles/solver_lib.dir/solver.cu.o"
},
{
  "directory": "/home/raid/sy451/Euler_CUDA/build/src/solver",
  "command": "/lsc/opt/cuda-11.7/bin/nvcc -forward-unknown-to-host-compiler  --options-file CMakeFiles/solver_lib.dir/includes_CUDA.rsp -std=c++17 \"--generate-code=arch=compute_52,code=[compute_52,sm_52]\" -x cu -c /home/raid/sy451/Euler_CUDA/src/solver/equationOfState.cu -o CMakeFiles/solver_lib.dir/equationOfState.cu.o",
  "file": "/home/raid/sy451/Euler_CUDA/src/solver/equationOfState.cu",
  "output": "src/solver/CMakeFiles/solver_lib.dir/equationOfState.cu.o"
}
]

As you can see, there is no -I flag with the include directory mentioned anywhere. However, when I create an analogous C++ project, it works fine, leading me to believe that the problem is with CMake and CUDA. The project compiles fine but it poses a problem when I use clangd. My temporary solution is to manually add the include flags to the compile_commands.json but it would be nice if the flag could be explicitly output.

Did you perhaps mean LIBCONFIG++_INCLUDE_DIRS here?

I’m getting the same behaviour. Any -I flag is not being forwarded to the compiler flags for nvcc, but is for regular C++ compilation. I do see that for nvcc, the compile_commands.json has a --options-file CMakelists/<>.rsp entry, whose file does have the include flags, but LSPs like clangd can’t read that.

I guess my question is, why are the include flags being placed into the *.rsp file instead of directly into the compile_commands.json for the cuda targets, but not regular C++ targets?

Yes, that’s what I meant!

Yeah I believe that is the case. One solution is to add these extra flags to the .clangd file.

From this issue here, it appears that there was a regression with clangd and reading the response files: clangd 17 regression: response files are not expanded when using command inference · Issue #69690 · llvm/llvm-project · GitHub

It appears that there was a way to not use the response files and have the include flags directly into the compile command by using -DCMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES=OFF, but I have not had success with that.

Based on what I read, it seems that this problem is likely to be fixed in clangd 18.

any update on this?