Skip to main content
Redhat Developers  Logo
  • AI

    Get started with AI

    • Red Hat AI
      Accelerate the development and deployment of enterprise AI solutions.
    • AI learning hub
      Explore learning materials and tools, organized by task.
    • AI interactive demos
      Click through scenarios with Red Hat AI, including training LLMs and more.
    • AI/ML learning paths
      Expand your OpenShift AI knowledge using these learning resources.
    • AI quickstarts
      Focused AI use cases designed for fast deployment on Red Hat AI platforms.
    • No-cost AI training
      Foundational Red Hat AI training.

    Featured resources

    • OpenShift AI learning
    • Open source AI for developers
    • AI product application development
    • Open source-powered AI/ML for hybrid cloud
    • AI and Node.js cheat sheet

    Red Hat AI Factory with NVIDIA

    • Red Hat AI Factory with NVIDIA is a co-engineered, enterprise-grade AI solution for building, deploying, and managing AI at scale across hybrid cloud environments.
    • Explore the solution
  • Learn

    Self-guided

    • Documentation
      Find answers, get step-by-step guidance, and learn how to use Red Hat products.
    • Learning paths
      Explore curated walkthroughs for common development tasks.
    • Guided learning
      Receive custom learning paths powered by our AI assistant.
    • See all learning

    Hands-on

    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.
    • Interactive labs
      Learn by doing in these hands-on, browser-based experiences.
    • Interactive demos
      Click through product features in these guided tours.

    Browse by topic

    • AI/ML
    • Automation
    • Java
    • Kubernetes
    • Linux
    • See all topics

    Training & certifications

    • Courses and exams
    • Certifications
    • Skills assessments
    • Red Hat Academy
    • Learning subscription
    • Explore training
  • Build

    Get started

    • Red Hat build of Podman Desktop
      A downloadable, local development hub to experiment with our products and builds.
    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.

    Download products

    • Access product downloads to start building and testing right away.
    • Red Hat Enterprise Linux
    • Red Hat AI
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat Developer Toolset

    References

    • E-books
    • Documentation
    • Cheat sheets
    • Architecture center
  • Community

    Get involved

    • Events
    • Live AI events
    • Red Hat Summit
    • Red Hat Accelerators
    • Community discussions

    Follow along

    • Articles & blogs
    • Developer newsletter
    • Videos
    • Github

    Get help

    • Customer service
    • Customer support
    • Regional contacts
    • Find a partner

    Join the Red Hat Developer program

    • Download Red Hat products and project builds, access support documentation, learning content, and more.
    • Explore the benefits

Remote LLVM development with Visual Studio Code

April 22, 2021
Konrad Kleine
Related topics:
C, C#, C++IDEsLinux
Related products:
Developer Toolset

    I used the Qt Creator IDE for most of my C++ work in the past. Then I joined Red Hat around mid-2016 and worked on a project with Go for three years. I quickly realized that I wanted something similar to Qt Creator. I’m a regular Vim user, but use it only for plain-text editing and not much more. I gave Vim a shot when really I was looking for something that works out of the box and can still be customized. As usual for a modern project, I needed to be able to do more than edit the files of one programming realm. Enter Visual Studio Code (VS Code).

    I can't say that VS Code worked out of the box. But being new to Go, I figured I would give it a try, especially because others were using it. Three years later, in 2019, I needed a change and joined our debuggers group to work on LLDB, a debugger that is part of the much larger LLVM project. LLVM also hosts Clang, a well-known compiler front-end for C-like languages.

    I began by checking out the LLVM codebase—which is huge, by the way—and compiling it on my local machine, which was very slow. You can read about my initial endeavor to speed up the compilation in this article. To sum things up: A notebook isn’t ideal when you want to code and compile with LLVM. The speed of compilation isn’t the only thing that matters. It’s the linking, as well, that can easily freeze my laptop. That said, distributed compilation using distcc or similar tools doesn't cut it.

    Our group in Red Hat has access to high-powered shared machines in Toronto (e.g., 56 cores with 256 GB of memory). I live in Germany, and at first I was skeptical whether I could successfully use those machines without too much latency. Qt Creator wasn’t a true option for editing files remotely because, as far as I know, it needed to run next to the code it was supposed to compile. After giving Vim and Emacs another shot for coding and compiling remotely, I went back to VS Code and found out that there’s a remote SSH extension. This article navigates you through how I’ve been using VS Code's remote SSH extension for editing and compiling LLVM, step by step.

    Prerequisites

    My base system is a laptop running the Fedora 32 operating system. For the sake of this tutorial, we’ll call the remote host just remote-host. If you want to follow the tutorial step by step, you can put the following into your ~/.ssh/config file to create an alias to whatever host you want:

    Host remote-host
      HostName YOUR_OWN_REMOTE_HOST_GOES_HERE
      User USER_NAME_WITH_WHICH_YOU_LOGIN_TO_YOUR_REMOTE_HOST

    Replace the obvious bits in that definition. Make sure you can log in to the remote host without entering a password by copying the public part of your SSH-key to the remote host: ssh-copy-id remote-host.

    Double-check that you can now log in using ssh remote-host. Now log back out.

    Setting up VS Code

    First, make sure you have a recent copy of VS Code or grab it from the download site. Once it's installed, you will need a bunch of extensions. To install the extensions I find useful when building and editing LLVM, run this snippet in the command line:

    $ for i in ms-vscode.cmake-tools \
    ms-vscode-remote.remote-ssh \
    ms-python.python \
    ms-vscode.cpptools \
    twxs.cmake \
    rreverser.llvm \
    jakob-erzar.llvm-tablegen \
    xaver.clang-format \
    pkief.material-icon-theme; do code --install-extension $i; done

    Preparing the remote host

    In my case, the architecture of the remote host (Fedora 31) and my laptop is the same: x86_64. I'm not sure if this always needs to be the case. I can confirm that instead of my Linux laptop and Linux remote host, I can use a Mac laptop and a Linux remote host. I'm sure the same is true for Windows.

    Log in to the remote host with:

    $ ssh remote-host

    Your remote host needs to have all the development tools installed that are required to build LLVM.

    Let's decide where to download LLVM and refer to it with an environment variable for now. In my case, the directory is not ~/ which would have simplified things a bit:

    $ export MYHOME=/opt/notnfs/kkleine/ # replace this with ~/

    Navigate to $MYHOME:

    $ cd $MYHOME

    Fetch the LLVM source tree:

    $ git clone https://github.com/llvm/llvm-project

    Now create a build directory inside the source directory:

    $ mkdir llvm-project/build

    This directory makes it simpler to find build files within the VS Code IDE later.

    Firing up VS Code

    When you start VS Code, it presents a screen like Figure 1.

    VS Code startup screen
    Figure 1: The VS Code startup screen.

    Notice the little green icon in the lower left corner of the screen. Click on it and select Remote-SSH: Connect Current Window to Host... as shown in Figure 2.

    Remote SSH Extension drop down
    Figure 2: Select 'Remote-SSH: Connect Current Window to Host...' from the menu.

    If you've configured your ~/.ssh/config properly, you can now select remote-host from the drop-down list. Notice that the green icon from before now shows Opening Remote ... and then turns into SSH: remote-host once you have connected successfully.

    Congratulations: You can now edit files on your remote host using VS Code. To test this, go to File—>Open File... and open the main CMakeLists.txt file from the LLVM project that you checked out earlier: /opt/notnfs/kkleine/llvm-project/llvm/CMakeLists.txt.

    Installing extensions remotely

    Let's head over to the extensions by clicking on the extensions symbol, which is a grid of squares. Notice that the side panel shows locally installed extensions and marks some with Install in SSH: remote-host. Click that little green icon to view all the extensions that can be installed on the remote host. Once that's done, click the blue Reload Required icon and enjoy all the extensions when developing remotely.

    Adjusting the settings

    We need to adjust some settings for CMake to work properly. Press Ctrl+Shift+P to open the command palette in Visual Studio Code and start typing >open remote set, as shown in Figure 3.

    Autofill in the command palette
    Figure 3: Autofill in the command palette.

    Then, click on Preferences: Open Remote Settings (SSH: remote-host). This should open up a settings.json file in a new tab, as shown in Figure 4.

    Open the remote settings file
    Figure 4: Open the remote settings file.

    This file is an empty JSON settings file, in my case. If you already have configurations in there, I assume that you have used VS Code before and know how to integrate my settings into yours. If your file is empty, you can copy the settings here:

    {
        //--------------------------------------------------------------------------
        //              C++
        //--------------------------------------------------------------------------
        "clang-format.fallbackStyle": "LLVM",
        "clang-format.style": "LLVM",
        "C_Cpp.clang_format_style": "LLVM",
        "C_Cpp.default.cppStandard": "c++14",
        "C_Cpp.default.cStandard": "c11",
        //--------------------------------------------------------------------------
        //              CMake
        //--------------------------------------------------------------------------
        "cmake.generator": "Ninja",
        // Adjust this path to the expansion of $MYHOME/llvm-project/llvm.
        "cmake.sourceDirectory": "/opt/notnfs/kkleine/llvm-project/llvm",
        // Adjust this path to the expansion of $MYHOME/llvm-project/build.
        "cmake.buildDirectory": "/opt/notnfs/kkleine/llvm-project/build",
        "cmake.configureSettings": {
            "LLVM_ENABLE_PROJECTS": ["clang","clang-tools-extra","compiler-rt","lld","mlir"],
            "CMAKE_EXPORT_COMPILE_COMMANDS": 1,
            "BUILD_SHARED_LIBS": "Off",
            "LLVM_BUILD_LLVM_DYLIB": "On",
            "LLVM_LINK_LLVM_DYLIB": "On",
            "CLANG_LINK_CLANG_DYLIB": "On",
            // I only need LLVM Backends to produce X86, decide what you need here!
            "LLVM_TARGETS_TO_BUILD": "X86",
            "LLVM_ENABLE_LDD": "On",
            "LLVM_CCACHE_BUILD": "On",
            "LLVM_CCACHE_MAXSIZE": "20G",
            "LLVM_ENABLE_IDE": "On",
            "LLVM_ENABLE_ASSERTIONS": "On",
            "LLVM_BUILD_EXAMPLES": "On",
            "LLVM_LIT_ARGS": "-v --xunit-xml-output test-results.xml",
            "PYTHON_EXECUTABLE": "/usr/bin/python3",
        },
        //--------------------------------------------------------------------------
        //              Editor
        //--------------------------------------------------------------------------
        "editor.mouseWheelZoom": true,
        "editor.renderIndentGuides": false,
        "editor.rulers": [80],
        "editor.formatOnPaste": false,
        "editor.renderWhitespace": "all",
        //--------------------------------------------------------------------------
        //              Misc
        //--------------------------------------------------------------------------
        "telemetry.enableTelemetry": false,
        "telemetry.enableCrashReporter": false,
        "[cpp]": {
            "editor.defaultFormatter": "xaver.clang-format"
        },
        "workbench.iconTheme": "material-icon-theme",
    }

    I've added a minimum of my personal settings to the JSON file. You can omit the Editor and Misc sections if you don't want them. When you are done, save the file with Ctrl+S.

    Configuring the LLVM project with CMake

    Click on File—>Open Folder and type in the expansion of $MYHOME/llvm-project (e.g.,~/llvm-project), as shown in Figure 5.

    Open folder dialog
    Figure 5: Type in the absolute path to the llvm-project folder.

    Open up the command palette in VS Code again by typing Ctrl+Shift+P followed by >cmake. This should bring up the list in Figure 6, from which you can select CMake: Select a Kit.

    CMake Select a Kit
    Figure 6: Select the 'CMake: Select a Kit' option.

    In the next dialog, shown in Figure 7, pick the compiler you want to use for compiling LLVM, or select [Scan for kits] if you don't see any options. (I chose Clang 9.0.1.)

    Select a Kit for LLVM Project
    Figure 7: VS Code presents the available compiler options.

    Next, you need to decide on the build variant in which CMake will configure your project. Bring back the command palette with Ctrl+Shift+P and Type CMake Select Variant, as shown in Figure 8.

    CMake Select Variant
    Figure 8: Select a build variant through 'CMake Select Variant'.

    Next, choose Release, as shown in Figure 9.

    Build Variant selection
    Figure 9: Choose Release as the build variant.

    Notice that the Status bar now looks like Figure 10. From now on, you can control which target you want to build from this bar.

    Status bar
    Figure 10: The status bar after choosing a build variant.

    If an output pane shows something like the following when the configuration is done, you've successfully configured LLVM:

    [cmake] -- Performing Test HAVE_POSIX_REGEX -- success
    [cmake] -- Performing Test HAVE_STEADY_CLOCK -- success
    [cmake] -- Configuring done
    [cmake] -- Generating done
    [cmake] -- Build files have been written to: /opt/notnfs/kkleine/llvm-project/build

    Note: You can read more about CMake in VS Code in the article Get started with CMake Tools on Linux.

    First build of Clang with VS Code

    Let's do our first build of Clang. Click on [all] in the status bar and type in clang to select the clang Executable. Notice that the status bar now shows [clang] instead of [all].

    Don't be afraid to hit that [Build] button to build the selected target.

    Something interesting is that VS Code doesn't care whether you chose Ninja or Make to build your project, because it calls CMake to invoke the underlying build system:

    [main] Building folder: llvm-project
    [build] Starting build
    [proc] Executing command: /usr/bin/cmake --build /opt/notnfs/kkleine/llvm-project/build --config Release --target clang -- -j 58
    [build] [58/2573   0% :: 0.383] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/ABIBreak.cpp.o
    [build] [59/2573   0% :: 0.462] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/COM.cpp.o/usr/bin/cmake --build /opt/notnfs/kkleine/llvm-project/build --config Release --target clang -- -j 58

    Bringing in a terminal

    VS Code does come with a terminal window. You can open it with Ctrl+` (the backtick character). The terminal looks like Figure 11.

    VS Code Terminal
    Figure 11: A command-line interface in the VS Code terminal window.

    Try testing your freshly built compiler with this snippet:

    $ cd build
    $ echo "int main(){return 42;}" | ./bin/clang++ -x c++ -
    $ ./a.out ; echo $?
    42

    I typically run some commands like ./bin/llvm-lit -v sometest in the terminal window. One nice thing about the terminal is that you can Ctrl+Click on any of the file paths to open them in the current VS Code window in a new tab. That makes opening and navigating files from the terminal extremely convenient.

    From here onward you can use all the goodies of VS Code, such as autocompletion, go-to declaration, switching between header and implementation, and so forth.

    Launching the configuration for LLVM-LIT

    To run llvm-lit -av current_file from inside VS Code, without using the terminal, you can bring back the command palette with Ctrl+Shift+P and type >launch to open the launch.json file. The menu displayed looks similar to Figure 12.

    Open Launch.json
    Figure 12: The menu displayed when you type '>launch' into the command palette.

    This file can contain multiple semi-generic configurations for programs you want to launch from time to time. Here's a configuration that will launch llvm-lit on the current file:

    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "llvm-lit current file",
                "type": "python",
                "request": "launch",
                "program": "/opt/notnfs/kkleine/llvm-project/build/bin/llvm-lit",
                "args": ["${fileBasename}"],
                "cwd": "${fileDirname}",
            }
            {
                "name": "llvm-lit all tests in current dir",
                "type": "python",
                "request": "launch",
                "program": "/opt/notnfs/kkleine/llvm-project/build/bin/llvm-lit",
                "args": ["."],
                "cwd": "${fileDirname}",
            }
        ]
    }

    You just need to adjust the path to point to your llvm-lit binary.

    Note: If the file hasn't been built yet, try building the all target or the check-llvm-tools-llvm-lit target.

    Let's open a specific lit file by pressing Ctrl+P. This opens a fuzzy dialog. Type ast-dump-decl.c and observe where the file is found (shown in Figure 13).

    Fuzzy file opening

    Once the file is opened, click on the debug symbol in the left-side bar to open a debugging pane. At this point we're not interested in debugging in the classic sense; we just want to launch llvm-lit. Click the small Play button (the triangle icon) next to your launch target name at the top of the screen. In this case, the launch target is llvm-lit current file. A terminal will open and show results like the following:

    $ cd /opt/notnfs/kkleine/llvm-project/clang/test/AST ; env /usr/bin/python /home/kkleine/.vscode-server/extensions/ms-python.python-2020.6.91350/pythonFiles/lib/python/debugpy/launcher 44349 -- /opt/notnfs/kkleine/llvm-project/build/bin/llvm-lit ast-dump-decl.c
    llvm-lit: /opt/notnfs/kkleine/llvm-project/build/bin/../../llvm/utils/lit/lit/llvm/config.py:347: note: using clang: /opt/notnfs/kkleine/llvm-project/build/bin/clang
    -- Testing: 1 tests, 1 workers --
    PASS: Clang :: AST/ast-dump-decl.c (1 of 1)
    
    Testing Time: 1.90s
      Passed: 1

    Feel free to run all the tests within the same directory as the current test file by selecting the other launch target, which is called llvm-lit all tests in current dir.

    Conclusion

    I hope you enjoyed reading this article—happy coding!

    Last updated: February 5, 2024

    Recent Posts

    • Protect data offloaded to GPU-accelerated environments with OpenShift sandboxed containers

    • Case study: Measuring energy efficiency on the x64 platform

    • How to prevent AI inference stack silent failures

    • Preventing GPU waste: A guide to JIT checkpointing with Kubeflow Trainer on OpenShift AI

    • How to manage TLS certificates used by OpenShift GitOps operator

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer tools
    • Interactive tutorials
    • API catalog

    Quicklinks

    • Learning resources
    • E-books
    • Cheat sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site status dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2026 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Chat Support

    Please log in with your Red Hat account to access chat support.