Skip to content

Commit 041e3f1

Browse files
committed
feat: move native binary to cgo
1 parent 8f4081a commit 041e3f1

File tree

104 files changed

+31763
-998
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+31763
-998
lines changed

.devcontainer/devcontainer.json

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,38 @@
11
{
22
"name": "JetKVM",
3-
"image": "mcr.microsoft.com/devcontainers/go:1-1.23-bookworm",
3+
"image": "mcr.microsoft.com/devcontainers/go:1.25-trixie",
44
"features": {
55
"ghcr.io/devcontainers/features/node:1": {
66
// Should match what is defined in ui/package.json
7-
"version": "22.15.0"
7+
"version": "22.19.0"
88
}
99
},
1010
"mounts": [
11-
"source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind,consistency=cached"
11+
"source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind,consistency=cached"
1212
],
13+
"onCreateCommand": ".devcontainer/install-deps.sh",
1314
"customizations": {
1415
"vscode": {
1516
"extensions": [
16-
"bradlc.vscode-tailwindcss",
17+
// coding styles
18+
"chrislajoie.vscode-modelines",
19+
"editorconfig.editorconfig",
20+
// GitHub
1721
"GitHub.vscode-pull-request-github",
18-
"dbaeumer.vscode-eslint",
22+
"github.vscode-github-actions",
23+
// Golang
1924
"golang.go",
25+
// C / C++
26+
"ms-vscode.cpptools",
27+
"ms-vscode.cpptools-extension-pack",
28+
// CMake / Makefile
2029
"ms-vscode.makefile-tools",
30+
"ms-vscode.cmake-tools",
31+
// Frontend
2132
"esbenp.prettier-vscode",
22-
"github.vscode-github-actions"
33+
"dbaeumer.vscode-eslint",
34+
"bradlc.vscode-tailwindcss"
2335
]
2436
}
2537
}
2638
}
27-

.devcontainer/install-deps.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/bin/bash
2+
3+
SUDO_PATH=$(which sudo)
4+
function sudo() {
5+
if [ "$UID" -eq 0 ]; then
6+
"$@"
7+
else
8+
${SUDO_PATH} "$@"
9+
fi
10+
}
11+
12+
set -ex
13+
14+
export DEBIAN_FRONTEND=noninteractive
15+
sudo apt-get update && \
16+
sudo apt-get install -y --no-install-recommends \
17+
build-essential \
18+
device-tree-compiler \
19+
gperf g++-multilib gcc-multilib \
20+
libnl-3-dev libdbus-1-dev libelf-dev libmpc-dev dwarves \
21+
bc openssl flex bison libssl-dev python3 python-is-python3 texinfo kmod cmake \
22+
wget zstd \
23+
python3-venv python3-kconfiglib \
24+
&& sudo rm -rf /var/lib/apt/lists/*
25+
26+
# Install buildkit
27+
BUILDKIT_VERSION="v0.2.5"
28+
BUILDKIT_TMPDIR="$(mktemp -d)"
29+
pushd "${BUILDKIT_TMPDIR}" > /dev/null
30+
31+
wget https://github.com/jetkvm/rv1106-system/releases/download/${BUILDKIT_VERSION}/buildkit.tar.zst && \
32+
sudo mkdir -p /opt/jetkvm-native-buildkit && \
33+
sudo tar --use-compress-program="unzstd --long=31" -xvf buildkit.tar.zst -C /opt/jetkvm-native-buildkit && \
34+
rm buildkit.tar.zst
35+
popd

.github/workflows/build.yml

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,48 @@ jobs:
1616
steps:
1717
- name: Checkout
1818
uses: actions/checkout@v5
19+
- name: Set up docker image context
20+
run: |
21+
./scripts/ci_helper.sh prepare
22+
- name: Set up Docker Buildx
23+
uses: docker/setup-buildx-action@v3
24+
- name: Build docker image
25+
uses: docker/build-push-action@v6
26+
with:
27+
context: ${{ env.DOCKER_BUILD_CONTEXT_DIR }}
28+
file: ${{ env.DOCKER_BUILD_CONTEXT_DIR }}/Dockerfile.build
29+
tags: ${{ env.DOCKER_BUILD_TAG }}
30+
push: false
31+
load: true
32+
- name: Set up Cmake cache
33+
uses: actions/cache@v4
34+
with:
35+
path: internal/native/cgo/build
36+
key: jetkvm-cgo-${{ hashFiles('internal/native/cgo/**/*.c', 'internal/native/cgo/**/*.h', 'internal/native/cgo/**/*.patch', 'internal/native/cgo/**/*.txt', 'internal/native/cgo/**/*.sh', '!internal/native/cgo/build/**') }}
37+
restore-keys: |
38+
jetkvm-cgo-${{ hashFiles('internal/native/cgo/**/*.c', 'internal/native/cgo/**/*.h', 'internal/native/cgo/**/*.patch', 'internal/native/cgo/**/*.txt', 'internal/native/cgo/**/*.sh', '!internal/native/cgo/build/**') }}
1939
- name: Set up Node.js
2040
uses: actions/setup-node@v5
2141
with:
2242
node-version: "22"
2343
cache: "npm"
2444
cache-dependency-path: "**/package-lock.json"
2545
- name: Set up Golang
26-
uses: actions/setup-go@v5
46+
uses: actions/setup-go@v6.0.0
2747
with:
28-
go-version: "1.24.4"
48+
go-version: "^1.25.1"
2949
- name: Build frontend
3050
run: |
3151
make frontend
32-
- name: Build application
52+
- name: Build application inside Docker container
3353
run: |
34-
make build_dev
54+
./scripts/ci_helper.sh make build_dev
3555
- name: Run tests
3656
run: |
3757
go test ./... -json > testreport.json
3858
- name: Make test cases
3959
run: |
40-
make build_dev_test
60+
./scripts/ci_helper.sh make build_dev_test
4161
- name: Golang Test Report
4262
uses: becheran/[email protected]
4363
with:

.gitignore

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,13 @@ static/*
33
.idea
44
.DS_Store
55

6-
device-tests.tar.gz
6+
.cache
7+
.vite
8+
.pnpm-store
9+
10+
device-tests.tar.gz
11+
node_modules
12+
13+
# generated during the build process
14+
#internal/native/include
15+
#internal/native/lib

.vscode/settings.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
{
2-
"tailwindCSS.classFunctions": ["cva", "cx"]
2+
"tailwindCSS.classFunctions": [
3+
"cva",
4+
"cx"
5+
],
6+
"git.ignoreLimitWarning": true
37
}

DEVELOPMENT.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,15 @@ tail -f /var/log/jetkvm.log
103103
├── ui/ # React frontend
104104
│ ├── src/routes/ # Pages (login, settings, etc.)
105105
│ └── src/components/ # UI components
106-
└── internal/ # Internal Go packages
106+
├── internal/ # Internal Go packages
107+
│ ├── native/ # CGO / Native code glue layer
108+
│ ├── native/cgo/ # C files for the native library (HDMI, Touchscreen, etc.)
109+
│ ├── native/eez/ # EEZ Studio Project files (for Touchscreen)
110+
│ ├── hidrpc/ # HIDRPC implementation for HID devices (keyboard, mouse, etc.)
111+
│ ├── logging/ # Logging implementation
112+
│ ├── usbgadget/ # USB gadget
113+
│ └── websecurity/ # TLS certificate management
114+
└── resource # netboot iso and other resources
107115
```
108116

109117
**Key files for beginners:**
@@ -136,6 +144,10 @@ npm install
136144
./dev_device.sh <YOUR_DEVICE_IP>
137145
```
138146

147+
### Touchscreen Changes
148+
149+
Please click the `Build` button in EEZ Studio then run `./dev_deploy.sh -r <YOUR_DEVICE_IP> --skip-ui-build` to deploy the changes to your device. Initial build might take more than 10 minutes as it will also need to fetch and build LVGL and other dependencies.
150+
139151
### Quick Backend Changes
140152

141153
*Best for: API or backend logic changes*
@@ -349,6 +361,17 @@ The application uses a JSON configuration file stored at `/userdata/kvm_config.j
349361
3. **Add migration logic if needed for existing installations**
350362

351363

364+
### LVGL Build
365+
366+
We modified the LVGL code a little bit to remove unused fonts and examples.
367+
The patches are generated by
368+
369+
```bash
370+
git diff --cached --diff-filter=d > ../internal/native/cgo/lvgl-minify.patch && \
371+
git diff --name-only --diff-filter=D --cached > ../internal/native/cgo/lvgl-minify.del
372+
```
373+
374+
352375
---
353376

354377
**Happy coding!**

Dockerfile.build

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# syntax=docker/dockerfile:1
2+
FROM --platform=${BUILDPLATFORM} golang:1.25.1-trixie AS builder
3+
4+
ENV GOTOOLCHAIN=local
5+
ENV GOPATH=/go
6+
ENV PATH=$GOPATH/bin:/usr/local/go/bin:$PATH
7+
8+
COPY install-deps.sh /install-deps.sh
9+
RUN /install-deps.sh
10+
11+
# Create build directory
12+
RUN mkdir -p /build/
13+
14+
# Copy go.mod and go.sum
15+
COPY go.mod go.sum /build/
16+
17+
WORKDIR /build
18+
19+
RUN go mod download && go mod verify
20+
21+
COPY entrypoint.sh /entrypoint.sh
22+
RUN chmod +x /entrypoint.sh
23+
24+
ENTRYPOINT [ "/entrypoint.sh" ]

Makefile

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ VERSION := 0.4.8
88
PROMETHEUS_TAG := github.com/prometheus/common/version
99
KVM_PKG_NAME := github.com/jetkvm/kvm
1010

11+
BUILDKIT_FLAVOR := arm-rockchip830-linux-uclibcgnueabihf
12+
BUILDKIT_PATH ?= /opt/jetkvm-native-buildkit
13+
SKIP_NATIVE_IF_EXISTS ?= 0
14+
SKIP_UI_BUILD ?= 0
1115
GO_BUILD_ARGS := -tags netgo,timetzdata,nomsgpack
1216
GO_RELEASE_BUILD_ARGS := -trimpath $(GO_BUILD_ARGS)
1317
GO_LDFLAGS := \
@@ -17,20 +21,40 @@ GO_LDFLAGS := \
1721
-X $(PROMETHEUS_TAG).Revision=$(REVISION) \
1822
-X $(KVM_PKG_NAME).builtTimestamp=$(BUILDTS)
1923

20-
GO_CMD := GOOS=linux GOARCH=arm GOARM=7 go
24+
GO_ARGS := GOOS=linux GOARCH=arm GOARM=7 ARCHFLAGS="-arch arm"
25+
# if BUILDKIT_PATH exists, use buildkit to build
26+
ifneq ($(wildcard $(BUILDKIT_PATH)),)
27+
GO_ARGS := $(GO_ARGS) \
28+
CGO_CFLAGS="-I$(BUILDKIT_PATH)/$(BUILDKIT_FLAVOR)/include -I$(BUILDKIT_PATH)/$(BUILDKIT_FLAVOR)/sysroot/usr/include" \
29+
CGO_LDFLAGS="-L$(BUILDKIT_PATH)/$(BUILDKIT_FLAVOR)/lib -L$(BUILDKIT_PATH)/$(BUILDKIT_FLAVOR)/sysroot/usr/lib -lrockit -lrockchip_mpp -lrga -lpthread -lm" \
30+
CC="$(BUILDKIT_PATH)/bin/$(BUILDKIT_FLAVOR)-gcc" \
31+
LD="$(BUILDKIT_PATH)/bin/$(BUILDKIT_FLAVOR)-ld" \
32+
CGO_ENABLED=1
33+
# GO_RELEASE_BUILD_ARGS := $(GO_RELEASE_BUILD_ARGS) -x -work
34+
endif
35+
36+
GO_CMD := $(GO_ARGS) go
37+
2138
BIN_DIR := $(shell pwd)/bin
2239

2340
TEST_DIRS := $(shell find . -name "*_test.go" -type f -exec dirname {} \; | sort -u)
2441

25-
hash_resource:
26-
@shasum -a 256 resource/jetkvm_native | cut -d ' ' -f 1 > resource/jetkvm_native.sha256
42+
build_native:
43+
@if [ "$(SKIP_NATIVE_IF_EXISTS)" = "1" ] && [ -f "internal/native/cgo/lib/libjknative.a" ]; then \
44+
echo "libjknative.a already exists, skipping native build..."; \
45+
else \
46+
echo "Building native..."; \
47+
CC="$(BUILDKIT_PATH)/bin/$(BUILDKIT_FLAVOR)-gcc" \
48+
LD="$(BUILDKIT_PATH)/bin/$(BUILDKIT_FLAVOR)-ld" \
49+
./scripts/build_cgo.sh; \
50+
fi
2751

28-
build_dev: hash_resource
52+
build_dev: build_native
2953
@echo "Building..."
3054
$(GO_CMD) build \
3155
-ldflags="$(GO_LDFLAGS) -X $(KVM_PKG_NAME).builtAppVersion=$(VERSION_DEV)" \
3256
$(GO_RELEASE_BUILD_ARGS) \
33-
-o $(BIN_DIR)/jetkvm_app cmd/main.go
57+
-o $(BIN_DIR)/jetkvm_app -v cmd/main.go
3458

3559
build_test2json:
3660
$(GO_CMD) build -o $(BIN_DIR)/test2json cmd/test2json
@@ -62,30 +86,32 @@ build_dev_test: build_test2json build_gotestsum
6286
tar czfv device-tests.tar.gz -C $(BIN_DIR)/tests .
6387

6488
frontend:
65-
cd ui && npm ci && npm run build:device && \
66-
find ../static/ \
67-
-type f \
68-
\( -name '*.js' \
69-
-o -name '*.css' \
70-
-o -name '*.html' \
71-
-o -name '*.ico' \
72-
-o -name '*.png' \
73-
-o -name '*.jpg' \
74-
-o -name '*.jpeg' \
75-
-o -name '*.gif' \
76-
-o -name '*.svg' \
77-
-o -name '*.webp' \
78-
-o -name '*.woff2' \
79-
\) \
80-
-exec sh -c 'gzip -9 -kfv {}' \;
89+
@if [ "$(SKIP_UI_BUILD)" = "1" ] && [ -f "static/index.html" ]; then \
90+
echo "Skipping frontend build..."; \
91+
else \
92+
cd ui && npm ci && npm run build:device && \
93+
find ../static/ -type f \
94+
\( -name '*.js' \
95+
-o -name '*.css' \
96+
-o -name '*.html' \
97+
-o -name '*.ico' \
98+
-o -name '*.png' \
99+
-o -name '*.jpg' \
100+
-o -name '*.jpeg' \
101+
-o -name '*.gif' \
102+
-o -name '*.svg' \
103+
-o -name '*.webp' \
104+
-o -name '*.woff2' \
105+
\) -exec sh -c 'gzip -9 -kfv {}' \; ;\
106+
fi
81107

82108
dev_release: frontend build_dev
83109
@echo "Uploading release... $(VERSION_DEV)"
84110
@shasum -a 256 bin/jetkvm_app | cut -d ' ' -f 1 > bin/jetkvm_app.sha256
85111
rclone copyto bin/jetkvm_app r2://jetkvm-update/app/$(VERSION_DEV)/jetkvm_app
86112
rclone copyto bin/jetkvm_app.sha256 r2://jetkvm-update/app/$(VERSION_DEV)/jetkvm_app.sha256
87113

88-
build_release: frontend hash_resource
114+
build_release: frontend build_native
89115
@echo "Building release..."
90116
$(GO_CMD) build \
91117
-ldflags="$(GO_LDFLAGS) -X $(KVM_PKG_NAME).builtAppVersion=$(VERSION)" \
@@ -101,4 +127,4 @@ release:
101127
@echo "Uploading release..."
102128
@shasum -a 256 bin/jetkvm_app | cut -d ' ' -f 1 > bin/jetkvm_app.sha256
103129
rclone copyto bin/jetkvm_app r2://jetkvm-update/app/$(VERSION)/jetkvm_app
104-
rclone copyto bin/jetkvm_app.sha256 r2://jetkvm-update/app/$(VERSION)/jetkvm_app.sha256
130+
rclone copyto bin/jetkvm_app.sha256 r2://jetkvm-update/app/$(VERSION)/jetkvm_app.sha256

cloud.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ func setCloudConnectionState(state CloudConnectionState) {
170170

171171
go waitCtrlAndRequestDisplayUpdate(
172172
previousState != state,
173+
"set_cloud_connection_state",
173174
)
174175
}
175176

config.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/json"
55
"fmt"
66
"os"
7+
"strconv"
78
"sync"
89

910
"github.com/jetkvm/kvm/internal/logging"
@@ -105,6 +106,25 @@ type Config struct {
105106
DefaultLogLevel string `json:"default_log_level"`
106107
}
107108

109+
func (c *Config) GetDisplayRotation() uint16 {
110+
rotationInt, err := strconv.ParseUint(c.DisplayRotation, 10, 16)
111+
if err != nil {
112+
logger.Warn().Err(err).Msg("invalid display rotation, using default")
113+
return 270
114+
}
115+
return uint16(rotationInt)
116+
}
117+
118+
func (c *Config) SetDisplayRotation(rotation string) error {
119+
_, err := strconv.ParseUint(rotation, 10, 16)
120+
if err != nil {
121+
logger.Warn().Err(err).Msg("invalid display rotation, using default")
122+
return err
123+
}
124+
c.DisplayRotation = rotation
125+
return nil
126+
}
127+
108128
const configPath = "/userdata/kvm_config.json"
109129

110130
var defaultConfig = &Config{

0 commit comments

Comments
 (0)