Files
serenity/Documentation/VSCodeConfiguration.md
T
Lucas Chollet cc0939a666 Everywhere: Stop using pc in our target triples
While `pc` is not particularly wrong on x86_64, it's nonsensical on
other supported platforms, namely aarch64 and riscv64.

For consistency, we now don't use this vendor anymore, regardless of the
platform.

Within the LLVM project, we now build as `$arch-serenity`. This is
enough in most cases, the only place where we have to specify a vendor
is the target .cfg file where we use `$arch-unknown-serenity`.

When building GCC and friends, again we simply identify as
`$arch-serenity` and this is enough.

As a result, the tools in Toolchain/Local/$arch/bin are now named after
this pattern: `$arch-serenity-$tool`.

These changes affect the toolchain build scripts, serenity's build
scripts and the Ports.

The last place where we should see `x86_64-pc-serenity` is the output of
`config.sub`, which assume the vendor is `pc` on vendor-less `x86*`
triples. So `x86_64-serenity` is expanded to `x86_64-pc-serenity`,
luckily enough and AFAICT, the whole GNU ecosystem considers `pc`,
`unknown` and vendor-less target triples the same. So `configure`
shouldn't have an issue finding the right tools anyway.

The gn files were edited with sed and are not tested.

This commit also includes a check in `Meta/serenity.sh` to give a nicer
error message when trying to build the system with an old toolchain.

----

To test this patch, on a clean tree I:
 - Ran `./Meta/serenity.sh x86_64 GNU`
 - Ran `./Toolchain/BuildJakt.sh`
 - Tested these ports: python3(configure based), libjxl(cmake based) and
   rizin(meson based)
 - Also booted on aarch64 and risv64

I also repeated the steps above with a Clang toolchain.

On a working tree I tested all the affected ports, the results are:
 - tinycc build fine but can't compile programs, I observed the same on
   master.
 - gdb and epsilon don't build but report the same errors as on master.
 - I manually edited the libgpg-error, and it builds fine.
 - The gcc port works fine.
2026-03-13 20:59:49 +01:00

13 KiB

Visual Studio Code Project Configuration

Visual Studio Code requires some configuration files, and a tailored settings.json file to understand serenity.

The WSL Remote extension allows you to use VS Code in Windows while using the normal WSL workflow. This works well, but for code comprehension speed you should put the Serenity directory on your WSL root partition.

The recommended extensions for VS Code include:

Code comprehension

Clangd has the best support for cross-compiling workflows, especially if configured as noted below. The Microsoft C/C++ tools can work, but require a lot more configuration and may not understand the sysroot in use.

See ClangdConfiguration for information on how to configure clangd.

DSL syntax highlighting

There's a syntax highlighter extension for SerenityOS DSLs called "SerenityOS DSL Syntax Highlight", available here or here. The extension provides syntax highlighting for LibIPC's IPC files, LibGUI's GUI Markup Language (GML), Web IDL, and LibJS's serialization format (no extension) as output by js with the -d option.

Microsoft C/C++ tools

This extension can be used as-is, but you need to point it to the custom Serenity compilers. Note that enabling the extension in the same workspace as the clangd and clang-format extensions will cause conflicts. If you choose to use Microsoft C/C++ Tools rather than clangd and clang-format, use the following c_cpp_properties.json to circumvent some errors. Even with the configuration in place, the extension will likely still report errors related to types and methods not being found.

.vscode/c_cpp_properties.json
{
    "configurations": [
        {
            "name": "userland-x86_64-gcc",
            "includePath": [
                "${workspaceFolder}",
                "${workspaceFolder}/Build/x86_64/",
                "${workspaceFolder}/Build/x86_64/Userland",
                "${workspaceFolder}/Build/x86_64/Userland/Applications",
                "${workspaceFolder}/Build/x86_64/Userland/Libraries",
                "${workspaceFolder}/Build/x86_64/Userland/Services",
                "${workspaceFolder}/Build/x86_64/Root/usr/include/**",
                "${workspaceFolder}/Userland",
                "${workspaceFolder}/Userland/Libraries",
                "${workspaceFolder}/Userland/Libraries/LibC",
                "${workspaceFolder}/Userland/Services",
                "${workspaceFolder}/Toolchain/Local/x86_64/x86_64-serenity/include/c++/**"
            ],
            "defines": ["DEBUG", "__serenity__"],
            "compilerPath": "${workspaceFolder}/Toolchain/Local/x86_64/bin/x86_64-serenity-g++",
            "cStandard": "c17",
            "cppStandard": "c++26",
            "intelliSenseMode": "linux-gcc-x86",
            "compileCommands": "Build/x86_64/compile_commands.json",
            "compilerArgs": ["-Wall", "-Wextra", "-Werror"],
            "browse": {
                "path": [
                    "${workspaceFolder}",
                    "${workspaceFolder}/Build/x86_64/",
                    "${workspaceFolder}/Build/x86_64/Userland",
                    "${workspaceFolder}/Build/x86_64/Userland/Applications",
                    "${workspaceFolder}/Build/x86_64/Userland/Libraries",
                    "${workspaceFolder}/Build/x86_64/Userland/Services",
                    "${workspaceFolder}/Build/x86_64/Root/usr/include/**",
                    "${workspaceFolder}/Userland",
                    "${workspaceFolder}/Userland/Libraries",
                    "${workspaceFolder}/Userland/Libraries/LibC",
                    "${workspaceFolder}/Userland/Services",
                    "${workspaceFolder}/Toolchain/Local/x86_64/x86_64-serenity/include/c++/**"
                ],
                "limitSymbolsToIncludedHeaders": true,
                "databaseFilename": "${workspaceFolder}/Build/x86_64/"
            }
        }
    ],
    "version": 4
}

Formatting

clangd provides code formatting out of the box using the clang-format engine. clang-format support is also included with the Microsoft C/C++ tools (see above). The settings below include a key that makes the Microsoft extension use the proper style.

Settings

These belong in the .vscode/settings.json of Serenity.

{
    // Excluding the generated directories keeps your file view clean and speeds up search.
    "files.exclude": {
        "**/.git": true,
        "Toolchain/Local/**": true,
        "Toolchain/Tarballs/**": true,
        "Toolchain/Build/**": true,
        "Build/**": true,
        "build/**": true
    },
    "search.exclude": {
        "**/.git": true,
        "Toolchain/Local/**": true,
        "Toolchain/Tarballs/**": true,
        "Toolchain/Build/**": true,
        "Build/**": true,
        "build/**": true
    },
    // Force clang-format to respect Serenity's .clang-format style file. This is not necessary if you're not using the Microsoft C++ extension.
    "C_Cpp.clang_format_style": "file",
    // Tab settings
    "editor.tabSize": 4,
    "editor.useTabStops": false,
    // format trailing new lines
    "files.trimFinalNewlines": true,
    "files.insertFinalNewline": true,
    // git commit message length
    "git.inputValidationLength": 72,
    "git.inputValidationSubjectLength": 72,
    // See ClangdConfiguration.md for arguments that may be needed.
    "clangd.arguments": [],
    // Set if needed.
    "clangd.path": "..."
}

Customization

Custom Tasks

You can create custom tasks (.vscode/tasks.json) to quickly compile Serenity. The following three example tasks should suffice in most situations, and allow you to specify the build system to use, as well as give you error highlighting.

Note: The Assertion und KUBSan Problem matchers will only run after you have closed qemu.

.vscode/tasks.json
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build lagom",
            "type": "shell",
            "problemMatcher": [
                {
                    "base": "$gcc",
                    "fileLocation": ["relative", "${workspaceFolder}/Build/lagom"]
                }
            ],
            "command": ["bash"],
            "args": ["-c", "\"Meta/serenity.sh build lagom\""],
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": false,
                "group": "build",
                "panel": "shared",
                "showReuseMessage": true,
                "clear": true
            }
        },
        {
            "label": "build",
            "type": "shell",
            "command": "bash",
            "args": ["-c", "Meta/serenity.sh build ${input:arch} ${input:compiler}"],
            "problemMatcher": [
                {
                    "base": "$gcc",
                    "fileLocation": [
                        "relative",
                        // FIXME: Clang uses ${input:arch}clang
                        "${workspaceFolder}/Build/${input:arch}"
                    ]
                },
                {
                    "source": "gcc",
                    "fileLocation": [
                        "relative",
                        // FIXME: Clang uses ${input:arch}clang
                        "${workspaceFolder}/Build/${input:arch}"
                    ],
                    "pattern": [
                        {
                            "regexp": "^([^\\s]*\\.S):(\\d*): (.*)$",
                            "file": 1,
                            "location": 2,
                            "message": 3
                        }
                    ]
                }
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },
        {
            "label": "launch",
            "type": "shell",
            "command": "bash",
            "args": ["-c", "Meta/serenity.sh run ${input:arch} ${input:compiler}"],
            "options": {
                "env": {
                    // Put your custom run configuration here, e.g. SERENITY_RAM_SIZE
                }
            },
            "problemMatcher": [
                {
                    "base": "$gcc",
                    "fileLocation": [
                        "relative",
                        // FIXME: Clang uses ${input:arch}clang
                        "${workspaceFolder}/Build/${input:arch}"
                    ]
                },
                {
                    "source": "gcc",
                    "fileLocation": [
                        "relative",
                        // FIXME: Clang uses ${input:arch}clang
                        "${workspaceFolder}/Build/${input:arch}"
                    ],
                    "pattern": [
                        {
                            "regexp": "^([^\\s]*\\.S):(\\d*): (.*)$",
                            "file": 1,
                            "location": 2,
                            "message": 3
                        }
                    ]
                },
                {
                    "source": "KUBSan",
                    "owner": "cpp",
                    "fileLocation": ["relative", "${workspaceFolder}"],
                    "pattern": [
                        {
                            "regexp": "KUBSAN: (.*)",
                            "message": 0
                        },
                        {
                            "regexp": "KUBSAN: at ../(.*), line (\\d*), column: (\\d*)",
                            "file": 1,
                            "line": 2,
                            "column": 3
                        }
                    ]
                },
                {
                    "source": "Assertion Failed",
                    "owner": "cpp",
                    "pattern": [
                        {
                            "regexp": "ASSERTION FAILED: (.*)$",
                            "message": 1
                        },
                        {
                            "regexp": "^((?:.*)\\.(h|cpp|c|S)):(\\d*)$",
                            "file": 1,
                            "location": 3
                        }
                    ],
                    "fileLocation": [
                        "relative",
                        // FIXME: Clang uses ${input:arch}clang
                        "${workspaceFolder}/Build/${input:arch}"
                    ]
                }
            ]
        }
    ],
    "inputs": [
        {
            "id": "compiler",
            "description": "Compiler to use",
            "type": "pickString",
            "default": "GNU",
            "options": ["GNU", "Clang"]
        },
        {
            "id": "arch",
            "description": "Architecture to compile for",
            "type": "pickString",
            "default": "x86_64",
            "options": ["x86_64", "aarch64"]
        }
    ]
}

License snippet

The following snippet may be useful if you want to quickly generate a license header, put it in .vscode/serenity.code-snippets:

{
    "License": {
        "scope": "cpp,c",
        "prefix": "license",
        "body": [
            "/*",
            " * Copyright (c) $CURRENT_YEAR, ${1:Your Name} <${2:[email protected]}>.",
            " *",
            " * SPDX-License-Identifier: BSD-2-Clause",
            " */"
        ],
        "description": "License header"
    }
}

Jakt

To use Jakt, build and install the jakt extension from the Jakt repository. A few configuration options are required to have import extern statements work correctly, which should go into your settings.json:

{
    // If you have installed jakt globally, you can omit this setting (though keep in mind that the compiler build *should* match the one in your serenity checkout)
    "jaktLanguageServer.compiler.executablePath": "Toolchain/Local/jakt/bin/jakt",

    "jaktLanguageServer.extraCompilerImportPaths": [
        ".",
        "Userland/Libraries",
        "Userland/Libraries/LibCrypt",
        "Userland/Libraries/LibSystem",
        "Userland/Services",
        "Userland",
        "Build/x86_64",
        "Build/x86_64/Userland/Services",
        "Build/x86_64/Userland/Libraries",
        "Build/x86_64/Userland"
    ]
}

Note that the build directories are architecture-specific, so you may need to adjust them if the generated headers are different per architecture.