> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/ask/flat/chapter-22-development-tools/di-22.1-jie-code-server-he-clangd-kai-fa-huan-jing.md).

# 22.1 code-server and clangd Development Environment

This section has been verified on 13.2-RELEASE and 14.0-RELEASE. For other versions, please refer with caution.

code-server is the open-source server version of VS Code. Due to compatibility issues with the upstream FreeBSD version of code-server, it can be run through the Arch Linux compatibility layer.

## Overview

code-server is the open-source server version of Visual Studio Code, which can run on remote servers and be accessed through a browser.

Due to compatibility issues with the upstream FreeBSD version of code-server, running code-server through the Linux compatibility layer remains a viable approach. This section uses the Arch Linux bootstrap image to build the Linux compatibility layer environment.

## Linux Compatibility Layer Path Mapping Mechanism

Leveraging the FreeBSD kernel's path redirection feature, although code-server runs using the Linux compatibility layer, clangd and all other development tools are still fully provided by FreeBSD. For the Linux compatibility layer's path redirection mechanism (i.e., the mechanism where Linux programs first look up the `/compat/linux/` path when accessing files, and fall back to the host system's native path if not found), refer to other relevant chapters in this book.

Taking code-server as an example, as a Linux program, it defaults to searching under **/compat/linux** first when attempting to access files or directories. Suppose you need to open the **/usr/src** directory to view the FreeBSD source tree - if **/compat/linux/usr/src** exists, then **/compat/linux/usr/src** will actually be opened instead of the intended **/usr/src**. Therefore, you need to remove **/compat/linux/usr/src** to ensure the FreeBSD kernel falls back to the correct **/usr/src**.

The same logic applies to clangd. Since **/compat/linux/bin/clangd** does not exist, when code-server attempts to start clangd, it ultimately calls **/usr/local/bin/clangd** provided by FreeBSD. The same applies to other development tools.

## Enable Linux Binary Compatibility on the Server and Deploy the archlinux-bootstrap Image

First, enable the Linux compatibility layer service and set it to start on boot:

```sh
# service linux enable   # Set the Linux compatibility layer service to start on boot
# service linux start    # Start the Linux compatibility layer service
```

The steps to download and extract the Arch Linux bootstrap image to `/compat/linux` (note that this section uses `/compat/linux` instead of `/compat/arch`), configure pacman mirrors, initialize the keyring, copy DNS configuration, and update the system are essentially the same as the Arch Linux compatibility layer construction method in other relevant chapters of this book. Only the key commands are listed here:

```sh
# fetch -o /tmp https://mirrors.bfsu.edu.cn/archlinux/iso/latest/archlinux-bootstrap-x86_64.tar.zst
# mkdir -p /compat/linux
# tar --use-compress-program=unzstd -xpvf /tmp/archlinux-bootstrap-x86_64.tar.zst -C /compat/linux --numeric-owner --strip-components=1
# rm /tmp/archlinux-bootstrap-x86_64.tar.zst
```

Edit **/compat/linux/etc/pacman.conf** to configure software mirrors (you need to add the archlinuxcn repository to install code-server), then execute:

```sh
# chroot /compat/linux pacman-key --init
# chroot /compat/linux pacman-key --populate
# cp /etc/resolv.conf /compat/linux/etc
# chroot /compat/linux pacman -Syu --noconfirm
# chroot /compat/linux pacman -S --noconfirm archlinuxcn-keyring
# chroot /compat/linux pacman -S --noconfirm code-server
```

## Remove Unnecessary Directories from the Arch Linux Runtime Environment on the Server

Remove directories in the Linux compatibility environment that may interfere with FreeBSD local path access:

```sh
# rm -Rf /compat/linux/home       # Remove the /home directory and its contents in the Linux compatibility layer
# rm -Rf /compat/linux/root       # Remove the /root directory and its contents in the Linux compatibility layer
# rm -Rf /compat/linux/usr/local  # Remove the /usr/local directory and its contents in the Linux compatibility layer
# rm -Rf /compat/linux/usr/src    # Remove the /usr/src directory and its contents in the Linux compatibility layer
```

Current directory status:

```sh
/compat/
└── linux/
    ├── home/ # User home directory (removed)
    ├── root/ # Root user home directory (removed)
    └── usr/
        ├── local/ # Local software directory (removed)
        └── src/ # Source code directory (removed)
```

## Install LLVM and the clangd Extension on the Server

Install the LLVM toolchain locally on FreeBSD and configure code-server:

```sh
# pkg install -y llvm   # Install the LLVM toolchain
# ln -sf /compat/linux/lib/code-server/bin/code-server /usr/local/bin   # Create a symlink for code-server to /usr/local/bin
# code-server --install-extension llvm-vs-code-extensions.vscode-clangd   # Install the clangd extension in code-server
```

Directory structure:

```sh
/
├── compat
│   └── linux
│       └── lib
│           └── code-server
│               └── bin
│                   └── code-server           # code-server executable
├── usr
│   └── local
│       └── bin
│           └── code-server                   # code-server symlink
└── root
    └── .code-server.pid                       # code-server PID file
```

## Start code-server via the daemon Command on the Server

Use the daemon utility to start code-server in the background, disable authentication, and write the PID to a specified file:

```sh
# daemon -p /root/.code-server.pid -f code-server --auth=none
```

> **Note**
>
> `--auth=none` disables the authentication mechanism of code-server. At this point, security is provided solely through the SSH tunnel (see below). Never expose a code-server instance with `--auth=none` directly on the public internet or local network, as anyone who can access the port could execute arbitrary code.
>
> Please be aware of the risks when operating with root privileges and ensure proper data backups.

## Establish an SSH Tunnel from the Client and Access the code-server Server via Browser

Establish SSH local port forwarding on the client, mapping local port 8080 to the remote server's **127.0.0.1:8080**:

```sh
# ssh -L 8080:127.0.0.1:8080 -N root@server  # -N means no remote command is executed, only network traffic forwarding
```

Access `http://127.0.0.1:8080` in the browser.

## (Example) Open the FreeBSD Source Tree in code-server in the Browser

Use code-server to open the **/usr/src** directory as the workspace:

```sh
# code-server /usr/src
```

## (Example) Compile a Minimal Kernel in the Browser and Generate the `compile_commands.json` File

Install the Bear tool and generate the compilation command database for the kernel build:

```sh
# pkg install bear   # Install the Bear tool for generating compile_commands.json
# bear --append -- make KERNCONF=MINIMAL buildkernel   # Use Bear to generate compilation commands for the kernel build, and build the MINIMAL kernel
```

After the compilation completes and the `compile_commands.json` file is generated, you can start reading the source code of key parts of the kernel.

## Automated Installation Script

To quickly set up the development environment, the following is an automated script for the code-server installation steps:

> **Warning**
>
> This script will destroy any existing Linux compatibility layer. Make sure you understand it before executing, and ensure proper backups.

```sh
#!/bin/sh

set -e

ARCHLINUX_MIRROR="https://mirrors.cernet.edu.cn/archlinux"
ARCHLINUXCN_MIRROR="https://mirrors.cernet.edu.cn/archlinuxcn"
FREEBSD_PKG_MIRROR="https://mirrors.cernet.edu.cn/FreeBSD-pkg"

rm -Rf /compat/linux
rm -Rf /tmp/archlinux-bootstrap-x86_64.tar.zst

service linux enable
service linux start

fetch -o /tmp "$ARCHLINUX_MIRROR/iso/latest/archlinux-bootstrap-x86_64.tar.zst"
mkdir -p /compat/linux
tar --use-compress-program=unzstd -xpvf /tmp/archlinux-bootstrap-x86_64.tar.zst -C /compat/linux --numeric-owner --strip-components=1

cat >/compat/linux/etc/pacman.conf <<EOF
[options]
Architecture = auto
ParallelDownloads = 5

[core]
Server = $ARCHLINUX_MIRROR/$repo/os/$arch
SigLevel = Required DatabaseOptional

[extra]
Server = $ARCHLINUX_MIRROR/$repo/os/$arch
SigLevel = Required DatabaseOptional

[archlinuxcn]
Server = $ARCHLINUXCN_MIRROR/$arch
SigLevel = Required DatabaseOptional
EOF

chroot /compat/linux pacman-key --init
chroot /compat/linux pacman-key --populate

cp /etc/resolv.conf /compat/linux/etc

chroot /compat/linux pacman --sync --refresh --sysupgrade --noconfirm
chroot /compat/linux pacman --sync --needed --noconfirm archlinuxcn-keyring
chroot /compat/linux pacman --sync --needed --noconfirm code-server

ln -sf /compat/linux/lib/code-server/bin/code-server /usr/local/bin

rm -Rf /compat/linux/home
rm -Rf /compat/linux/root
rm -Rf /compat/linux/usr/local
rm -Rf /compat/linux/usr/src

pkg install -y git bash vim htop tmux llvm bear

code-server --install-extension llvm-vs-code-extensions.vscode-clangd
code-server --install-extension mhutchie.git-graph

rm -Rf /tmp/archlinux-bootstrap-x86_64.tar.zst
```

Directory structure:

```sh
/
├── compat
│   └── linux
│       ├── etc
│       │   ├── pacman.conf             # Arch Linux pacman configuration file
│       │   └── resolv.conf             # DNS resolution configuration (copied from FreeBSD)
│       ├── lib
│       │   └── code-server
│       │       └── bin
│       │           └── code-server     # code-server executable
│       └── usr
│           ├── local                     # (removed)
│           └── src                       # (removed)
├── usr
│   ├── local
│   │   └── bin
│   │       ├── code-server             # code-server symlink (points to /compat/linux/lib/code-server/bin/code-server)
│   │       └── clangd                   # clangd executable
│   └── src                              # FreeBSD source code directory (used as code-server workspace)
└── root
    └── .code-server.pid                 # code-server process ID file
```

Readers are advised to test and verify on their own.

## Supplementary Notes

### HTTPS Configuration

This section does not cover how to serve code-server over HTTPS on the server. If you need to configure HTTPS, refer to the official code-server documentation for SSL certificate configuration.

### Linux Compatibility Layer vs. Linux Jail

This section uses the Linux binary compatibility layer, not Linux Jail. The main difference between the two is that the Linux compatibility layer shares the FreeBSD kernel, while Linux Jail provides a more isolated runtime environment.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.bsdcn.org/ask/flat/chapter-22-development-tools/di-22.1-jie-code-server-he-clangd-kai-fa-huan-jing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
