====== Get started with C++ and VSCodium ====== This page describes how to get started with C++ development, first using nothing but a cpp file and a simple makefile, created without a specific editor. Once that works, it continues with describing how to use that same makefile within [[https://vscodium.com/|VSCodium]]. An advantage to use VSCodium is that it offers practical guidance during writing, helping to write code faster. ===== Creating a Hello World makefile project ===== This section shows how to setup a Hello World project from scratch, to begin with without VSCodium, using a makefile for building the application with four targets: * make * make all * make run * make clean ==== HelloWorld.cpp ==== Copy paste the following lines into your command line: cd ../project/cpp/etc. <-- Change this path to a location where you want to place your project mkdir HelloWorld cd !$ # NB. !$ repeats the 2nd part of the previous command (See bash history substitution) mkdir build src cat << 'EOF' > src/HelloWorld.cpp #include using namespace std; int main(int argc, char** argv) { cout << "Hello World!" << endl; } EOF ==== makefile ==== (NB. For the makefile, if necessary, use [[https://www.browserling.com/tools/spaces-to-tabs|spaces-to-tabs]] to convert spaces to tabs) cat << 'EOF' > makefile # # A simple makefile for compiling a c++ project # # The compiler to use, per default this is already CXX for g++ # as can be seen with "make -p", so no additional definition # necessary for CXX (like defining: CXX = g++) # compiler flags: # -g adds debugging information to the executable file # -Wall turns on most, but not all, compiler warnings CCFLAGS = -g -Wall # paths -L LDFLAGS += # libraries -l: LDLIBS += # Source directory SRCDIR = src # Output directory BUILDDIR = build # Find C source files recursively SOURCES = $(shell find $(SRCDIR) -type f -name '*.cpp') # Generate object file names based on source file names OBJECTS = $(patsubst $(SRCDIR)/%.c,$(BUILDDIR)/%.o,$(SOURCES)) # Main target TARGET = HelloWorld .PHONY: all all: $(BUILDDIR)/$(TARGET) # Note 1: PHONY is important here. Without it, implicit rules will try to build the # executable "all", since the prereqs are ".o" files. # Note 2: See https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html # for the meaning of expressions like: @D, $<, and $@ $(BUILDDIR)/$(TARGET): $(OBJECTS) $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@ # Compile each source file $(BUILDDIR)/%.o : $(SRCDIR)/%.cpp @mkdir -p $(@D) $(CXX) $(CCFLAGS) -c $< -o $@ run: $(BUILDDIR)/$(TARGET) @$(BUILDDIR)/$(TARGET) clean: rm -rf $(BUILDDIR)/$(TARGET) EOF When done, try to make HelloWorld: make Which will default to the target make all. If no error appears, try to run: make run ===== Installing and setting up VSCodium ===== This section describes how to install and setup VSCodium for writing C++ code. Once the installation/configuration is completed, the description will continue with showing a basic "Hello World!" C++ project and how to use that makefile within VSCodium. It will be possible to import the previous project and use editing features from clangd like code completion, type awareness, compile errors and more. ==== VSCodium Installation ==== VSCodium can be installed with apt on Debian/ubuntu. Follow the instructions given here: [[https://vscodium.com/#install-on-debian-ubuntu-deb-package]]. If you are using Ubuntu MATE with the global menu bar enabled, a system component (vala-appmenu-applet) crashes when placing VSCodium into the background with the keyboard shortcut ALT + TAB. When this happens the menu bar (mate-panel) suddenly disappears but quickly comes back. A workaround is to change in VSCodium the titlebar style to: native in vscode preferences. With the "Install/configure ... VSCodium" shell script from below this can be done automatically from the shell. ==== VSCodium Configuration ==== In order to work with and debug C++ code with VSCodium, two extensions, clangd and codelldb needs to be installed. The standard way to install an extension in VSCodium is to click on the Extensions tab and search and install accordingly. Alternatively, the extensions can be installed from the command line using the method in the box below. When using the command line, make sure to quit VSCodium in case it is running and jump to the instruction "... Install C++ extensions from the command line". Start VSCodium (from the command line by typing //codium//) press Ctrl + Shift + X and search and install the following extensions: * clangd (llvm-vs-code-extensions) IDE features like autocompletion and bug detection for C++ using the Clang compiler * CodeLLDB (vadimcn) A native debugger extension for VSCode/VSCodium based on LLDB (Please note that CodeLLDB needs to install a further architecture specific file, which, once installed, also requires the extension to restart. ^ //(Alternative) Install C++ extensions from the command line// ^ | To kind of automate this and prevent VSCodium to download additionally a 32MB file once CodeLLDB is installed (and prevent a required restart of this extension), you can install all extensions directly from the command line. First download the vsix extensions. For this create a target directory for your extension (vsix) files. Use for example $HOME/Maintenance/apps/VSCodium_vsix/\\     • From [[https://github.com/vadimcn/codelldb/releases]] download the latest "codelldb-linux-x64.vsix" to the target directory\\     • From [[https://marketplace.visualstudio.com/_apis/public/gallery/publishers/llvm-vs-code-extensions/vsextensions/vscode-clangd/0.6.0/vspackage]] ((Get the most recent version from the following page: [[https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd]] and find the latest version below the text "More Info")) download the vsix file to the target directory\\ Then instead install the file with something like:\\ codium --install-extension $HOME/Maintenance/apps/VSCodium_vsix/codelldb-linux-x64.vsix codium --install-extension $HOME/Maintenance/apps/VSCodium_vsix/llvm-vs-code-extensions.vscode-clangd-0.6.0.vsix | The extension clangd depends on the clangd language server [[https://clangd.llvm.org/|clangd]], which is confusing, since both the language server and the extension have the same name. Before the extension can be used, the language server needs to be installed. To automatically install using the command line, jump to the instruction "... Install C++ extensions from the command line". Otherwise proceed as following to install manually: Download clangd-linux-22.1.6.zip from [[https://github.com/clangd/clangd/releases]]. And extract this to: $HOME/.config/VSCodium/User/globalStorage/llvm-vs-code-extensions.vscode-clangd/install/22.1.6/clangd_22.1.6/ Then configure the clangd.path in VSCodium to: $HOME/.config/VSCodium/User/globalStorage/llvm-vs-code-extensions.vscode-clangd/install/21.1.6/clangd_22.1.6/bin/clangd ^ //Install/configure clangd language server, titleBarStyle and telemetry with VSCodium automatically//((References: https://ubuntu-mate.community/t/vscode-kills-panel/29174/2)) ^ | # To execute, copy paste al lines in a terminal CLANGDPATH="$(find "$HOME/.config/VSCodium/User/globalStorage/llvm-vs-code-extensions.vscode-clangd/install/" -maxdepth 4 -name "clangd" -print -quit 2>/dev/null)" if [ -z "${CLANGDPATH}" ]; then echo "Downloading and installing clangd language server..." CLANGDVER="$(curl -s https://github.com/clangd/clangd | grep "/clangd/clangd/releases/tag/" | sed 's|.*tag/\(.*\)">|\1|')" if [ -n "${CLANGDVER}" ]; then mkdir -p "$HOME/.config/VSCodium/User/globalStorage/llvm-vs-code-extensions.vscode-clangd/install/${CLANGDVER}" mkdir -p "$HOME/.config/VSCodium/User/globalStorage/llvm-vs-code-extensions.vscode-clangd/download/${CLANGDVER}" cd !$ wget --quiet --show-progress -O "clangd-linux-${CLANGDVER}.zip" "https://github.com/clangd/clangd/releases/download/${CLANGDVER}/clangd-linux-${CLANGDVER}.zip" unzip -d "$HOME/.config/VSCodium/User/globalStorage/llvm-vs-code-extensions.vscode-clangd/install/${CLANGDVER}" "clangd-linux-${CLANGDVER}.zip" CLANGDPATH="$HOME/.config/VSCodium/User/globalStorage/llvm-vs-code-extensions.vscode-clangd/install/${CLANGDVER}/clangd_${CLANGDVER}/bin/clangd" else echo "Unable to find latest clangd version, press ctrl + c to abort" sleep infinity fi fi # $1: variable to configure (E.g. clangd.path ) # $2: parameter to set (double quotes need to be included if required) # $3: target file replace_or_set_json_entry () { # removing current entry from file sed -i "/\"$1\": .*/d" "$3" # add a line under the first curly brace _with_ a trailing comma sed -i "/^{/a \ \ \ \ \"$1\": $2," "$3" # then remove only the very last comma sed -i ':begin;$!N;s/,\n}/\n}/g;tbegin;P;D' $3 } modify_vscodium_settings () { # take care of case when settings.json is empty if [ ! -s "$HOME/.config/VSCodium/User/settings.json" ]; then printf "{\n}\n" > "$HOME/.config/VSCodium/User/settings.json" fi replace_or_set_json_entry "clangd.path" "\"${CLANGDPATH}\"" "$HOME/.config/VSCodium/User/settings.json" replace_or_set_json_entry "window.titleBarStyle" "\"native\"" "$HOME/.config/VSCodium/User/settings.json" replace_or_set_json_entry "telemetry.feedback.enabled" "false" "$HOME/.config/VSCodium/User/settings.json" } # set clangd.path in VSCodium accordingly if [ -f "$HOME/.config/VSCodium/User/settings.json" ]; then # verify leading { and trailing } brackets if [ ! -s "$HOME/.config/VSCodium/User/settings.json" -o "$(head -n 1 "$HOME/.config/VSCodium/User/settings.json")" = "{" -a "$(tail -n 1 "$HOME/.config/VSCodium/User/settings.json")" = "}" ]; then modify_vscodium_settings else printf "Unable to modify VSCodium settings.json at $HOME/.config/VSCodium/User/\nFile not json compliant\n" fi else # file settings.json is not present mkdir -p "$HOME/.config/VSCodium/User" modify_vscodium_settings fi | Once done, continue with creating a C++ Hello World makefile project as described below. ===== Using VSCodium with the makefile project ===== Once the C++ code can be compiled and executed with the makefile, it is then possible to use VSCodium and assign the makefile accordingly. As a whole, VSCodium may offer some advantages for editing and troubleshooting your code. To integrate a makefile project into VSCodium, it is necessary to provide a special (hidden) directory with the name .vscode, at the root of the project directory, with the following json files((Taken from: https://forum.juce.com/t/how-to-set-up-vscodium-to-compile-and-debug-juce-projects-using-makefiles-written-by-projucer-debian-gnu-linux/54505)): ^ Configuration file ^ Description ^ Dependency ^ | [[https://code.visualstudio.com/docs/debugtest/tasks|tasks.json]] | Holds one or more build configurations. Each holds build instructions for a type of executable to be built. A specific compiler can be specified for each. | Essential | | [[https://code.visualstudio.com/docs/debugtest/debugging-configuration|launch.json]] | Holds one or more debug configurations, each holds settings on how a specific executable will be debugged. | Essential | To create these files for the HelloWorld project, cd into the root directory of your HelloWorld project and copy-paste the following: === # create a .vscode directory === mkdir .vscode === # tasks.json === cat << 'EOF' > .vscode/tasks.json { "version": "2.0.0", "tasks": [ { "label": "build", "type": "shell", "command": "make", "group": { "kind": "build", "isDefault": true }, "options": { "cwd": "${workspaceFolder}/" } } ] } EOF === # launch.json === cat << 'EOF' > .vscode/launch.json { "version": "0.2.0", "configurations": [ { "name": "Compile with make and launch project.", "type": "lldb", "request": "launch", "program": "${workspaceFolder}/build/${workspaceFolderBasename}", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "Set Disassembly Flavor to Intel", "text": "-gdb-set disassembly-flavor intel", "ignoreFailures": true } ], "preLaunchTask": "build", "miDebuggerPath": "/usr/bin/gdb" } ] } EOF While still being at the root directory of your project, start VSCodium with providing the project path: codium . You should see something like the following window: | {{:pub:software:development:vscodium:cpp:vscodium_project_first_view.png?direct&400|}} | | //VSCodium first screen after opening via command line"// | If it looks differently, type Ctrl + Shift + P in VSCodium and enter without quotes: "Clear Recently Opened" and also close the editor by typing Ctrl + W. After that, if you open the project from the command line again, it should look like in the picture. ==== Build your project the first time ==== Open the HelloWorld.cpp file by navigating to it. Then type Ctrl + Shift + B. It should now build your project, using your makefile. To run your project without debugging, you can hit F5 (or Ctrl + F5). ===== VSCodium - further steps ===== Instead of using a makefile for the project, consider using cmake instead, because there is better support for it in vscodium. To understand how to use a cmake hello world project in vscodium, [[http://todo.com|follow this page]]. Also, there are more configuration files, which can be used for certain features in the .vscode directory: ^ Configuration file ^ Description ^ Dependency ^ | c_cpp_properties.json | Holds the compiler(s) path(s) and C/C++ IntelliSense settings. | Essential | | settings.json | Holds configuration files parameter variables which can hold text values that can be substituted in some (not all) Visual Studio Code options to allow text substitution. An alternative to option $env variables which should work but do not work. | Essential | References: * https://earthly.dev/blog/vscode-make/ * https://codeplay.com/portal/blogs/2023/03/01/setting-up-c-development-with-visual-studio-code-on-ubuntu * https://rbessick5.georgetown.domains/tcv.html * https://forum.juce.com/t/how-to-set-up-vscodium-to-compile-and-debug-juce-projects-using-makefiles-written-by-projucer-debian-gnu-linux/54505/2 * https://inpyjama.com/post/makefile-2/ * https://p3ld3v.medium.com/c-hello-world-with-make-and-cmake-97740bd9dd7e ===== Tips and Tricks ===== ==== Using the format library ==== If you need to use [[https://github.com/fmtlib/fmt|fmt]], the open-source formatting library, install libfmt-dev: sudo apt update && sudo apt install libfmt-dev Then include this into your project with the following include directive: #include #include // or more general using namespace std; using namespace fmt; // Note that fmt::format or fmt::print will not work with V10 anymore as it did with v9 int main(int argc, char** argv) { int a = 5; cout << format("The value is {}", a) << endl; print("The value is: {}\n", a); } And in the makefile, inform the compiler about the usage of the fmt library by adding it to LDLIBS, like: LDLIBS += -lfmt If you do not want or are unable to change the makefile, you can add "#define FMT_HEADER_ONLY" at the very first line of the C++ file, like: #define FMT_HEADER_ONLY #include #include using namespace fmt; // Note that fmt::format or fmt::print will not work with V10 anymore as it did with v9 int main() { print("The value is: {}\n", 42); }