A VSCode epiphany

A VSCode epiphany
DALL-E: "A collection of different sized engines connected by spaghetti, photorealistic"

I ran into an issue on Jetbrains CLion that prevented the debugger from working, so I decided to give VS Code for a spin for C++ development.  

This post will cover a few topics:

  1. Running and debugging CMake projects in VS Code
  2. Recognizing include directories for 3rd party libs
  3. An epiphany about how to think about VS Code

Running and debugging CMake projects in VS Code

Let's say you have an existing CMake based project and you want to edit it in VS Code.  For example, a trivial project that depends on OpenCV.  (btw on OSX you will need to brew install opencv first)

Given a folder with two files:

CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(opencv_experiments)

set(CMAKE_CXX_STANDARD 14)

find_package(OpenCV REQUIRED)

include_directories(.)

include_directories( ${OpenCV_INCLUDE_DIRS} )

message(OpenCV_INCLUDE_DIRS="${OpenCV_INCLUDE_DIRS}")


add_executable(opencv_experiments
        main.cpp)

target_link_libraries( opencv_experiments ${OpenCV_LIBS} )

main.cpp

#include <cstdio>
#include <iostream>
#include <opencv2/imgcodecs.hpp>

int main(int argc, char **argv) {
    cv::Mat image = cv::imread("path/to/image.jpg");
    std::cout << "image rows " << image.rows << std::endl;
}

Open the containing directory in VSCode.  You should see a screen like this:

Your first instinct might be to run the project in using the run button in the top right corner:

It will now ask you to choose a compiler (why do I have so many!?)

Then you will get hit with a plethora of confusing errors:

I spent some time going down the rabbit hole to figure out why this didn't work.  Here's what I found.

Understanding what went wrong

As explained by this awesome YouTube video by D Bersan, what's happening is essentially this:

VS Code as a whole knows nothing about your CMakeLists.txt file.  

Luckily though, there's an extension for that: the CMake Tools extension from Microsoft.  With that installed, we can use the facilities provided by the extension to build and run code, and ignore the "normal" VSCode buttons for building and running code.

VSCode + CMake

First install these two extensions:

  1. CMake Tools extension from Microsoft
  2. The Microsoft C/C++ extension

After these extensions are installed, if you click the icon for the CMake Tools extension, the panel will be empty.  

Next you need to "CMake: Configure" from the command palette so that the CMake Tools extension will recognize your project.  (why is this so hard?  see epiphany below)

In order to configure, you will have to pick a compiler.  Choose Clang, because it's based on LLVM and is less insane than GCC.

Now CMake will recognize your project:

Note that you should see:

  1. Content in the CMake Project panel on the left
  2. CMake output in the "Output" in the bottom panel
  3. In the blue bottom bar, it should show the compiler you chose (Clang)

Running code, with CMake this time

In the bottom blue toolbar, you will see the debug and run icons.  Hit the run icon.

It will build and run the code, and display the output in the terminal:

You can also put a breakpoint somewhere and it will stop at the breakpoint, now you can do step through debugging.

What about those annoying squiggly lines?

Is this driving you crazy too?

As described in this YouTube video by BoostMyTool, you need to tell VS Code about the directory with the include files for OpenCV.

Hit quick fix and edit include path setting:

Click the c_cpp_properties.json link:

Add the path to the opencv include files:

Now it will recognize the code and things like autocomplete will work!

and you can also "Command-click" into library functions to see the docs and usage:

But wait, what's that single little squiggly!?

If you look closely, there's still a single squiggly:

Why can't it find the file?  Why is it trying to use gcc when I told it to use clang?

Unfortunately, even after quite a lot of googling, I couldn't figure it out.  

DALL-E: "A person having a nightmare about squiggly lines"

This is one of those times that I'm glad I don't have OCD, because even though that squiggly is annoying, I'm just going to ignore it and get on with my development.

If you manage to figure it out, please DM me on twitter!

An epiphany about how to think about VS Code

VS Code is not an IDE.  It's not "integrated".  

If you approach VS Code with the expectation to get the same experience as what you get an IDE (like I did), you will probably get very frustrated.

Instead, you should expect papercuts like:

  • Seeing two "Run code" play-icon buttons, one of which does exactly as you want, the other which is totally broken.  A good IDE would never confuse the user like that.
  • Having to manually run "Cmake Config" in order to even get the CMake "Run code" button.  A good IDE would do that for you.
  • Having to manually tell VS Code about the OpenCV include file directory.  A good IDE would do that for you.

On the plus side, if you're willing to roll up your sleeves and dig in, you can probably get it working!  A lot of these components are open source, and so you can contribute by filing issues and pull requests.  

That's a beautiful thing that the proprietary IDEs can't compete with.