[Solved] VScode Error: find_package(catkin) failed

Question:

In vscode, when using cmake for configure, I found that the CMakeLists.txt generated by catkin_init_workspace reported an error:
find_package(catkin) failed. catkin was neither found in the workspace···

analysis:

After investigation and analysis, it is found that there is a problem with the following code in CMakeLists.txt:

# use command ‘catkin_init_workspace’  to generate ‘CMakeLists.txt’
set(catkin_search_path "")
  foreach(path ${CMAKE_PREFIX_PATH})
    if(EXISTS "${path}/.catkin")
      list(FIND catkin_search_path ${path} _index)
      if(_index EQUAL -1)
        list(APPEND catkin_search_path ${path})
      endif()
    endif()
  endforeach()

Specifically, the path from the variable ${CMAKE_PREFIX_PATH} is not searched for .catkin.
By directly modifying the /opt/ros/melodic/share/catkin/cmake/toplevel.cmake print variable ${CMAKE_PREFIX_PATH} pointed to by CMakeLists.txt, the output was found to be empty.
However, the configure in the system terminal works, and the command executed is the same as the configure in vscde, as follows

# The actual command executed when configure with cmake-tool in vscode
/usr/bin/cmake \
--no-warn-unused-cli \
-DCMAKE_PREFIX_PATH=/opt/ros/melodic \
-DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Release \
-DCMAKE_C_COMPILER:FILEPATH=/usr/bin/x86_64-linux-gnu-gcc-7 \
-DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/x86_64-linux-gnu-g++-7 \
-S/home/will/allpros/avp_slam_sim \
-B/home/will/allpros/avp_slam_sim/build_vsc \
-G "Unix Makefiles"

Also, even if you add export CMAKE_PREFIX_PATH=/opt/ros/melodic:$CMAKE_PREFIX_PATH to ~/.bashrc, you will still get an error after restarting the computer and doing configure, where the path /opt/ros/melodic was determined when installing ros Of course, you can also use the command find / -iname *.catkin or locate *.catkin to find the specific path.
To summarize.
The reason for this is unclear. It is suspected that the environment variable ${CMAKE_PREFIX_PATH} obtained by vscode during cmake-configure is empty, but when using the system terminal ${CMAKE_PREFIX_PATH} has the value /opt/ros/melodic, which comes from the source /opt/ros/melodic at boot time. source /opt/ros/melodic/setup.bash, which is already written in the ~/.bashrc auto-execution file when we installed ROS, and after booting, echo $CMAKE_PREFIX_PATH in system terminal can output /opt/ros/melodic normally. .

Solution:
1. modify the system file directly

$ sudo gedit /opt/ros/melodic/share/catkin/cmake/toplevel.cmake

Add the following in /opt/ros/melodic/share/catkin/cmake/toplevel.cmake

list(APPEND CMAKE_PREFIX_PATH "/opt/ros/melodic")

The results are as follows:

# toplevel CMakeLists.txt for a catkin workspace
# catkin/cmake/toplevel.cmake

cmake_minimum_required(VERSION 3.0.2)

project(Project)

set(CATKIN_TOPLEVEL TRUE)

list(APPEND CMAKE_PREFIX_PATH "/opt/ros/melodic")

# search for catkin within the workspace
set(_cmd "catkin_find_pkg" "catkin" "${CMAKE_SOURCE_DIR}")
execute_process(COMMAND ${_cmd}
  RESULT_VARIABLE _res
  OUTPUT_VARIABLE _out
  ERROR_VARIABLE _err
  OUTPUT_STRIP_TRAILING_WHITESPACE
  ERROR_STRIP_TRAILING_WHITESPACE
)
...
...
...

2. add attribute in cmake setting of vscode

Ctrl+Shift+P –> preferences: open settings (JSON)
add:

"cmake.configureArgs": [
        "-DCMAKE_PREFIX_PATH=/opt/ros/melodic"
    ],

Read More: