From: Matthias Maier Date: Fri, 12 May 2023 16:05:22 +0000 (-0500) Subject: CMake: create a compile_commands.json symlink X-Git-Tag: v9.5.0-rc1~230^2~1 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4bc8e6890e61a30740562da0af87104efdb6e2e2;p=dealii.git CMake: create a compile_commands.json symlink Modern IDEs such as VSCode use a separate build directory for configuring and compiling a project (such as our example steps). Unfortunately, this sometimes confuses language servers such as clangd that might fail to find the correct compile_commands.json in that build directory. Let's work around this issue by simply creating a symlink from the source directory pointing to the compile_commands.json file. As a sanity check, if there is already a compile_commands.json file present, or if the source and build directory are the same we simply do nothing. --- diff --git a/cmake/macros/macro_deal_ii_invoke_autopilot.cmake b/cmake/macros/macro_deal_ii_invoke_autopilot.cmake index 26fd8736f4..417301d7d7 100644 --- a/cmake/macros/macro_deal_ii_invoke_autopilot.cmake +++ b/cmake/macros/macro_deal_ii_invoke_autopilot.cmake @@ -46,14 +46,38 @@ macro(deal_ii_invoke_autopilot) set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) - # Define and setup a compilation target: + # + # Make sure that compile_commands.json is available in the source + # directory (to help IDEs like VSCode with clangd for code analysis): + # + + # In order to check whether we have an "in source" build we have to make + # sure to remove all symlinks and resolve to absolute file paths. This is + # necessary because with symlinks CMAKE_SOURCE_DIR and CMAKE_BINARY dir + # might look different but are in fact the same (fully resolved) + # directory... + get_filename_component(_source "${CMAKE_SOURCE_DIR}" REALPATH) + get_filename_component(_build "${CMAKE_BINARY_DIR}" REALPATH) + if(NOT "${_source}" STREQUAL "${_build}") + # Ensure that we do not override "compile_commands.json" in the source + # directory if already present and then create a symlink using the + # (unresolved) CMAKE_BINARY_DIR variable. + if(NOT EXISTS "${CMAKE_SOURCE_DIR}/compile_commands.json") + file(CREATE_LINK + "${CMAKE_BINARY_DIR}/compile_commands.json" + "${CMAKE_SOURCE_DIR}/compile_commands.json" + SYMBOLIC + ) + endif() + endif() + + # Define and set up a compilation target: add_executable(${TARGET} ${TARGET_SRC}) deal_ii_setup_target(${TARGET}) message(STATUS "Autopilot invoked") # Define a custom target to easily run the program: - if(NOT DEFINED TARGET_RUN) set(TARGET_RUN ${TARGET}) endif()