]> https://gitweb.dealii.org/ - dealii.git/commitdiff
CMake: create a compile_commands.json symlink
authorMatthias Maier <tamiko@43-1.org>
Fri, 12 May 2023 16:05:22 +0000 (11:05 -0500)
committerMatthias Maier <tamiko@43-1.org>
Fri, 12 May 2023 22:27:23 +0000 (17:27 -0500)
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.

cmake/macros/macro_deal_ii_invoke_autopilot.cmake

index 26fd8736f4aa39b7a99867a615a121c95da682bd..417301d7d781acd0c5eaeb0f9d497ae43ffbd632 100644 (file)
@@ -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()

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.