4 Commits
fix/ci ... main

Author SHA1 Message Date
3536329079 Merge pull request 'feat: 添加看门狗与重连机制' (#7) from fix/issue-32 into main
Some checks failed
backend / cross (aarch64) (push) Failing after 5m4s
backend / cross (arm) (push) Failing after 14m38s
backend / cross (armhf) (push) Failing after 3m48s
backend / cross (i686) (push) Failing after 3m35s
backend / cross (mips) (push) Failing after 2m40s
backend / cross (mips64) (push) Failing after 30s
backend / cross (mips64el) (push) Failing after 6m45s
backend / cross (mipsel) (push) Failing after 31s
backend / cross (s390x) (push) Failing after 31s
backend / cross (win32) (push) Failing after 1m31s
backend / cross (x86_64) (push) Failing after 2m32s
docker / build (push) Failing after 3m48s
Reviewed-on: #7
2026-01-09 01:36:28 +00:00
hwy
7460892e49 feat: 添加看门狗与重连机制
Some checks failed
backend / cross (aarch64) (push) Failing after 10m50s
backend / cross (arm) (push) Failing after 33m58s
backend / cross (armhf) (push) Failing after 1m31s
backend / cross (i686) (push) Failing after 31s
backend / cross (mips) (push) Failing after 1m30s
backend / cross (mips64) (push) Failing after 4m35s
backend / cross (mips64el) (push) Failing after 34m37s
backend / cross (mipsel) (push) Failing after 16m38s
backend / cross (s390x) (push) Failing after 5m54s
backend / cross (win32) (push) Failing after 11m53s
backend / cross (x86_64) (push) Failing after 11m50s
backend / cross (aarch64) (pull_request) Failing after 4m39s
backend / cross (arm) (pull_request) Failing after 1m31s
backend / cross (armhf) (pull_request) Failing after 3m18s
backend / cross (i686) (pull_request) Failing after 1m31s
backend / cross (mips) (pull_request) Failing after 31s
backend / cross (mips64) (pull_request) Failing after 31s
backend / cross (mips64el) (pull_request) Failing after 31s
backend / cross (mipsel) (pull_request) Failing after 31s
backend / cross (s390x) (pull_request) Failing after 30s
backend / cross (win32) (pull_request) Failing after 2m43s
backend / cross (x86_64) (pull_request) Failing after 1m53s
- 添加内部断开后的自动重试机制
- 优化终端连接稳定性
2026-01-08 22:58:18 +08:00
98c3b9322b Merge pull request 'fix/issue-32-attach failed 添加逻辑以防止命令过早执行,导致连接开发容器失败' (#6) from fix/issue-32 into main
Some checks failed
backend / cross (aarch64) (push) Failing after 34m32s
backend / cross (arm) (push) Failing after 11s
backend / cross (armhf) (push) Failing after 4m41s
backend / cross (i686) (push) Failing after 31s
backend / cross (mips) (push) Failing after 30s
backend / cross (mips64) (push) Failing after 6m40s
backend / cross (mips64el) (push) Failing after 11s
backend / cross (mipsel) (push) Failing after 16m40s
backend / cross (s390x) (push) Failing after 1m32s
backend / cross (win32) (push) Failing after 1m32s
backend / cross (x86_64) (push) Failing after 31s
docker / build (push) Failing after 31s
Reviewed-on: #6
2026-01-07 10:47:49 +00:00
hwy
1681f9e4ef 添加逻辑以防止命令过早执行,导致连接开发容器失败
Some checks failed
backend / cross (aarch64) (pull_request) Failing after 6m40s
backend / cross (arm) (pull_request) Failing after 1m32s
backend / cross (armhf) (pull_request) Failing after 31s
backend / cross (i686) (pull_request) Failing after 31s
backend / cross (mips) (pull_request) Failing after 31s
backend / cross (mips64) (pull_request) Failing after 4m49s
backend / cross (mips64el) (pull_request) Failing after 1m31s
backend / cross (mipsel) (pull_request) Failing after 30s
backend / cross (s390x) (pull_request) Failing after 30s
backend / cross (win32) (pull_request) Failing after 31s
backend / cross (x86_64) (pull_request) Failing after 10m17s
2026-01-07 18:34:02 +08:00
6 changed files with 16545 additions and 16332 deletions

View File

@@ -23,7 +23,7 @@ jobs:
matrix: matrix:
target: [i686, x86_64, arm, armhf, aarch64, mips, mipsel, mips64, mips64el, s390x, win32] target: [i686, x86_64, arm, armhf, aarch64, mips, mipsel, mips64, mips64el, s390x, win32]
steps: steps:
- uses: https://devstar.cn/actions/checkout@v4 - uses: actions/checkout@v4
- name: Install packages - name: Install packages
run: | run: |
sudo apt-get update sudo apt-get update
@@ -32,3 +32,8 @@ jobs:
env: env:
BUILD_TARGET: ${{ matrix.target }} BUILD_TARGET: ${{ matrix.target }}
run: ./scripts/cross-build.sh run: ./scripts/cross-build.sh
- uses: actions/upload-artifact@v4
with:
name: ttyd.${{ matrix.target }}
path: build/ttyd*

View File

@@ -12,7 +12,7 @@ jobs:
packages: write packages: write
contents: read contents: read
steps: steps:
- uses: https://devstar.cn/actions/checkout@v4 - uses: actions/checkout@v4
- name: Install packages - name: Install packages
run: | run: |
sudo apt-get update sudo apt-get update
@@ -25,36 +25,32 @@ jobs:
[ "$arch" = "armv7" ] && arch="arm" [ "$arch" = "armv7" ] && arch="arm"
mkdir -p dist/$arch && cp build/ttyd dist/$arch/ttyd mkdir -p dist/$arch && cp build/ttyd dist/$arch/ttyd
done done
- uses: https://devstar.cn/alexios/setup-qemu-action@v3 - uses: docker/setup-qemu-action@v3
- uses: https://devstar.cn/alexios/setup-buildx-action@v3 - uses: docker/setup-buildx-action@v3
- uses: https://devstar.cn/alexios/login-action@v3 - uses: docker/login-action@v3
with: with:
username: ${{ secrets.DOCKER_HUB_USER }} username: ${{ secrets.DOCKER_HUB_USER }}
password: ${{ secrets.DOCKER_HUB_TOKEN }} password: ${{ secrets.DOCKER_HUB_TOKEN }}
- uses: https://devstar.cn/alexios/login-action@v3 - uses: docker/login-action@v3
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Determine docker tags - name: Determine docker tags
id: docker_tag id: docker_tag
env:
DOCKER_USER: ${{ vars.DOCKER_HUB_USERNAME }}
PROJECT: ${{ vars.PROJECT_NAME }}
run: | run: |
FULL_IMAGE_NAME="${DOCKER_USER}/${PROJECT}"
case $GITHUB_REF in case $GITHUB_REF in
refs/tags/*) refs/tags/*)
TAG_NAME=${GITHUB_REF#refs/tags/} TAG_NAME=${GITHUB_REF#refs/tags/}
echo "DOCKER_TAG=${FULL_IMAGE_NAME}:${TAG_NAME}" >> $GITHUB_ENV echo "DOCKER_TAG=tsl0922/ttyd:${TAG_NAME}" >> $GITHUB_ENV
echo "ALPINE_TAG=${FULL_IMAGE_NAME}:${TAG_NAME}-alpine" >> $GITHUB_ENV echo "ALPINE_TAG=tsl0922/ttyd:${TAG_NAME}-alpine" >> $GITHUB_ENV
;; ;;
*) *)
echo "DOCKER_TAG=${FULL_IMAGE_NAME}:latest" >> $GITHUB_ENV echo "DOCKER_TAG=tsl0922/ttyd:latest" >> $GITHUB_ENV
echo "ALPINE_TAG=${FULL_IMAGE_NAME}:alpine" >> $GITHUB_ENV echo "ALPINE_TAG=tsl0922/ttyd:alpine" >> $GITHUB_ENV
esac esac
- name: build/push docker image - name: build/push docker image
uses: https://devstar.cn/alexios/build-push-action@v6 uses: docker/build-push-action@v6
with: with:
context: . context: .
file: ./Dockerfile file: ./Dockerfile
@@ -64,7 +60,7 @@ jobs:
${{ env.DOCKER_TAG }} ${{ env.DOCKER_TAG }}
ghcr.io/${{ env.DOCKER_TAG }} ghcr.io/${{ env.DOCKER_TAG }}
- name: build/push docker image (alpine) - name: build/push docker image (alpine)
uses: https://devstar.cn/alexios/build-push-action@v6 uses: docker/build-push-action@v6
with: with:
context: . context: .
file: ./Dockerfile.alpine file: ./Dockerfile.alpine

View File

@@ -14,16 +14,15 @@ jobs:
build: build:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: https://devstar.cn/actions/checkout@v4 - uses: actions/checkout@v4
- uses: https://devstar.cn/actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 18
- name: Run yarn install, check and build - name: Run yarn install, check and build
run: | run: |
corepack enable corepack enable
corepack prepare yarn@stable --activate corepack prepare yarn@stable --activate
yarn install --no-immutable yarn install
yarn add -D eslint-plugin-n
yarn run check yarn run check
yarn run build yarn run build
working-directory: html working-directory: html

View File

@@ -82,6 +82,7 @@ export class Xterm {
private textDecoder = new TextDecoder(); private textDecoder = new TextDecoder();
private written = 0; private written = 0;
private pending = 0; private pending = 0;
private attachWatchdogTick = 0;
private terminal: Terminal; private terminal: Terminal;
private fitAddon = new FitAddon(); private fitAddon = new FitAddon();
@@ -112,6 +113,9 @@ export class Xterm {
private containerStatus = ""; private containerStatus = "";
private attachCommandSent = false; private attachCommandSent = false;
private attachCommandSentAt?: number; private attachCommandSentAt?: number;
private ptyOutputReceived = false;
private attachWatchdogId?: NodeJS.Timeout;
private commandLoadInFlight = false;
constructor( constructor(
private options: XtermOptions, private options: XtermOptions,
private sendCb: () => void private sendCb: () => void
@@ -122,6 +126,10 @@ export class Xterm {
d.dispose(); d.dispose();
} }
this.disposables.length = 0; this.disposables.length = 0;
if (this.attachWatchdogId) {
clearInterval(this.attachWatchdogId);
this.attachWatchdogId = undefined;
}
} }
@bind @bind
@@ -276,6 +284,8 @@ export class Xterm {
@bind @bind
public connect() { public connect() {
this.socket = new WebSocket(this.options.wsUrl, ['tty']); this.socket = new WebSocket(this.options.wsUrl, ['tty']);
this.ptyOutputReceived = false;
this.attachWatchdogTick = 0;
const { socket, register } = this; const { socket, register } = this;
socket.binaryType = 'arraybuffer'; socket.binaryType = 'arraybuffer';
@@ -283,11 +293,31 @@ export class Xterm {
register(addEventListener(socket, 'message', this.onSocketData as EventListener)); register(addEventListener(socket, 'message', this.onSocketData as EventListener));
register(addEventListener(socket, 'close', this.onSocketClose as EventListener)); register(addEventListener(socket, 'close', this.onSocketClose as EventListener));
register(addEventListener(socket, 'error', () => (this.doReconnect = false))); register(addEventListener(socket, 'error', () => (this.doReconnect = false)));
}
@bind
private startAttachWatchdog() {
if (this.attachWatchdogId) return;
this.attachWatchdogId = setInterval(() => {
this.attachWatchdogTick++;
if (this.connectStatus) return;
this.tryExecuteAttachCommand();
if (!this.connectStatus) this.loadCommandOnce();
}, 2000);
}
@bind
private stopAttachWatchdog() {
if (!this.attachWatchdogId) return;
clearInterval(this.attachWatchdogId);
this.attachWatchdogId = undefined;
} }
@bind @bind
private onSocketOpen() { private onSocketOpen() {
console.log('[webTerminal] WebSocket opened, containerStatus:', this.containerStatus, 'connectStatus:', this.connectStatus, 'attachCommandSent:', this.attachCommandSent); console.log('[webTerminal] WebSocket opened, containerStatus:', this.containerStatus, 'connectStatus:', this.connectStatus, 'attachCommandSent:', this.attachCommandSent);
console.log('[webTerminal] onSocketOpen - postAttachCommand:', this.postAttachCommand?.length || 0, 'ptyOutputReceived:', this.ptyOutputReceived, 'commandLoadInFlight:', this.commandLoadInFlight);
const { textEncoder, terminal, overlayAddon } = this; const { textEncoder, terminal, overlayAddon } = this;
const msg = JSON.stringify({ AuthToken: this.token, columns: terminal.cols, rows: terminal.rows }); const msg = JSON.stringify({ AuthToken: this.token, columns: terminal.cols, rows: terminal.rows });
@@ -310,6 +340,10 @@ export class Xterm {
this.doReconnect = this.reconnect; this.doReconnect = this.reconnect;
this.initListeners(); this.initListeners();
terminal.focus(); terminal.focus();
// Check if can execute pending command
console.log('[webTerminal] onSocketOpen - calling tryExecuteAttachCommand()');
this.tryExecuteAttachCommand();
} }
@bind @bind
@@ -340,6 +374,45 @@ export class Xterm {
} }
} }
@bind
private tryExecuteAttachCommand() {
if (this.connectStatus) {
console.log('[Xterm] tryExecuteAttachCommand: already connected');
return;
}
if (!this.postAttachCommand || this.postAttachCommand.length === 0) {
console.log('[Xterm] tryExecuteAttachCommand: no command available');
return;
}
if (this.socket?.readyState !== WebSocket.OPEN) {
console.log('[Xterm] tryExecuteAttachCommand: WebSocket not ready, state:', this.socket?.readyState);
return;
}
if (!this.ptyOutputReceived) {
console.log('[Xterm] tryExecuteAttachCommand: ttyd not ready yet (waiting for first output)');
return; // Wait for TTY readiness confirm via output
}
// 如果已发送没连上,允许超时后重发
const shouldResend =
this.attachCommandSent &&
this.attachCommandSentAt !== undefined &&
Date.now() - this.attachCommandSentAt > 5000;
if (this.attachCommandSent && !shouldResend) {
console.log('[Xterm] tryExecuteAttachCommand: command already sent, not resending yet');
return;
}
const cmd = this.postAttachCommand[0];
if (cmd) {
console.log('[Xterm] ✅ All conditions met, executing attach command...');
this.sendData(cmd + "\n");
this.attachCommandSent = true;
this.attachCommandSentAt = Date.now();
console.log('[Xterm] Command sent at:', new Date(this.attachCommandSentAt).toISOString());
}
}
/** /**
* 获取 URL 查询参数 * 获取 URL 查询参数
*/ */
@@ -363,6 +436,12 @@ export class Xterm {
*/ */
@bind @bind
public loadCommandOnce() { public loadCommandOnce() {
if (this.commandLoadInFlight) {
console.log('[Xterm] loadCommandOnce: command load already in flight, skipping');
return;
}
console.log('[Xterm] loadCommandOnce: starting command load...');
this.commandLoadInFlight = true;
this.loadCommandWithRetry(0); this.loadCommandWithRetry(0);
} }
@@ -375,6 +454,7 @@ export class Xterm {
const maxRetries = 5; const maxRetries = 5;
const { params, baseUrl } = this.getUrlParams(); const { params, baseUrl } = this.getUrlParams();
console.log(`[Xterm] loadCommandWithRetry: attempt ${retryCount + 1}/${maxRetries}, fetching command from ${baseUrl}/devcontainer/command?${params}`);
fetch(`${baseUrl}/devcontainer/command?${params}`) fetch(`${baseUrl}/devcontainer/command?${params}`)
.then(response => { .then(response => {
if (!response.ok) { if (!response.ok) {
@@ -393,14 +473,10 @@ export class Xterm {
} }
// 执行连接容器的命令(只执行一次) // 执行连接容器的命令(只执行一次)
const parts = data.command.split('\n'); console.log('[Xterm] Command loaded successfully, attempting to execute...');
if (parts[0] && !this.connectStatus) { this.postAttachCommand = data.command.split('\n');
console.log('[Xterm] Successfully loaded connection command, executing...'); this.tryExecuteAttachCommand();
this.sendData(parts[0]+"\n"); this.commandLoadInFlight = false;
this.attachCommandSent = true;
this.attachCommandSentAt = Date.now();
}
this.postAttachCommand = parts;
}) })
.catch(error => { .catch(error => {
console.error(`[Xterm] Error loading command (attempt ${retryCount + 1}/${maxRetries}):`, error); console.error(`[Xterm] Error loading command (attempt ${retryCount + 1}/${maxRetries}):`, error);
@@ -415,12 +491,26 @@ export class Xterm {
} else { } else {
console.error('[Xterm] Failed to load command after all retries'); console.error('[Xterm] Failed to load command after all retries');
// 可以在这里显示错误提示给用户 // 可以在这里显示错误提示给用户
this.commandLoadInFlight = false;
} }
}); });
} }
@bind @bind
public changeContainerStatus(v: string){ public changeContainerStatus(v: string){
const oldStatus = this.containerStatus;
this.containerStatus = v; this.containerStatus = v;
const { options } = this.getUrlParams();
if (options.get('type') !== 'docker') return;
const statusNum = parseInt(v);
const oldStatusNum = oldStatus ? parseInt(oldStatus) : -1;
// 检测到状态 9已停止启动 watchdog等待容器启动
if (statusNum === 9 && !this.connectStatus) {
console.log('[Xterm] Container is stopped (status 9), starting attach watchdog to wait for startup');
this.startAttachWatchdog();
}
} }
@bind @bind
@@ -465,48 +555,85 @@ export class Xterm {
const data = rawData.slice(1); const data = rawData.slice(1);
switch (cmd) { switch (cmd) {
case Command.OUTPUT: case Command.OUTPUT:
if (!this.ptyOutputReceived) {
this.ptyOutputReceived = true;
console.log('[Xterm] OUTPUT: ttyd is now ready (received first output), attempting to execute attach command');
this.tryExecuteAttachCommand();
}
const decodedData = textDecoder.decode(data); const decodedData = textDecoder.decode(data);
console.log('[ttyd] output:', decodedData); const pure = this.stripAnsi(decodedData);
const compactOutput = decodedData.replace(/\s/g, ''); const compactOutput = decodedData.replace(/\s/g, '');
const { options } = this.getUrlParams(); const { options } = this.getUrlParams();
if (options.get('type') === 'docker') { if (options.get('type') === 'docker') {
// 保存host的标题 // 保存 host的标题
if (this.hostTitle === ''){ const pureContent = this.stripAnsi(decodedData).trim();
this.hostTitle = compactOutput; if (!this.connectStatus && !this.attachCommandSent && this.hostTitle === '' && pureContent.length > 0) {
this.hostTitle = pureContent;
} }
// 检测是否退出devcontainer标题等于host的标题
if (this.connectStatus && compactOutput.includes(this.hostTitle)){ // 检测是否退出 devcontainer
if (this.connectStatus && this.hostTitle && pureContent === this.hostTitle) {
this.connectStatus = false; this.connectStatus = false;
this.connectionMessageBuffer = ''; this.connectionMessageBuffer = '';
this.attachCommandSent = false; this.attachCommandSent = false;
this.attachCommandSentAt = undefined; this.attachCommandSentAt = undefined;
this.postAttachCommandStatus = false; this.postAttachCommandStatus = false;
} if (this.socket?.readyState === WebSocket.OPEN) {
// 检测连接完成:监听 "Successfully connected to the devcontainer" 消息 this.ptyOutputReceived = true;
// 这条消息是由连接命令中的 echo "$WEB_TERMINAL_HELLO" 输出的 } else {
if (!this.connectStatus) { this.ptyOutputReceived = false;
const sanitizedOutput = this.stripAnsi(decodedData).replace(/\r/g, '\n');
const combinedOutput = this.connectionMessageBuffer + sanitizedOutput;
const segments = combinedOutput.split(/\n/);
this.connectionMessageBuffer = segments.pop() ?? '';
const hasSuccessLine = segments.some(line => line.trim() === 'Successfully connected to the devcontainer');
if (hasSuccessLine) {
this.connectStatus = true;
this.connectionMessageBuffer = '';
this.attachCommandSentAt = undefined;
console.log('[Xterm] Connection established, enabling terminal input');
// 确保终端输入已启用
this.terminal.options.disableStdin = false;
} }
this.startAttachWatchdog();
} }
// 连接完成之前,过滤掉 docker exec 命令的标题输出ANSI 码和 docker-H 开头的输出)
if ( if (this.connectStatus) {
!(this.connectStatus === false && try {
(textDecoder.decode(data).includes('\x1b') || this.writeFunc(data);
textDecoder.decode(data).replace(/\s/g, '').includes('docker-H'))) } catch (e) {
){ console.error('[Xterm] writeFunc error:', e);
this.writeFunc(data); }
} else {
// 未连接状态:缓冲所有输出
this.connectionMessageBuffer += decodedData;
// docker exec 失败时(容器不存在/未运行),只重置状态,让 watchdog 定时重试
const lower = pure.toLowerCase();
const isDockerExecError =
lower.includes('error response from daemon') &&
(lower.includes('is not running') || lower.includes('no such container') || lower.includes('cannot connect'));
if (isDockerExecError) {
this.attachCommandSent = false;
this.attachCommandSentAt = undefined;
this.connectionMessageBuffer = '';
}
const successMarker = 'Successfully connected to the devcontainer';
// 尝试在 buffer 中查找成功标记
const markerIndex = this.connectionMessageBuffer.indexOf(successMarker);
if (markerIndex !== -1) {
console.log('[Xterm] ✅ Connection established! Found success marker in buffer');
this.connectStatus = true;
this.terminal.options.disableStdin = false;
this.stopAttachWatchdog();
const validOutput = this.connectionMessageBuffer.substring(markerIndex);
this.writeData(validOutput);
this.connectionMessageBuffer = '';
} else {
// 调试:如果命令已发送但还没连接成功,检查 buffer 内容
if (this.attachCommandSent && !this.connectStatus && this.connectionMessageBuffer.length > 0) {
const bufferPreview = this.connectionMessageBuffer.substring(0, 200).replace(/\n/g, '\\n').replace(/\r/g, '\\r');
console.log('[Xterm] Waiting for connection success... buffer length:', this.connectionMessageBuffer.length, 'preview:', bufferPreview);
}
}
if (this.connectionMessageBuffer.length > 20000) {
this.connectionMessageBuffer = this.connectionMessageBuffer.slice(-5000);
} }
}
// 连接完成且出现容器的标题且没有执行过postAttach命令 // 连接完成且出现容器的标题且没有执行过postAttach命令
if (this.connectStatus && compactOutput.includes(this.workdir) && !this.postAttachCommandStatus){ if (this.connectStatus && compactOutput.includes(this.workdir) && !this.postAttachCommandStatus){
console.log('[Xterm] Detected workdir in output, executing postAttachCommand'); console.log('[Xterm] Detected workdir in output, executing postAttachCommand');
@@ -525,6 +652,12 @@ export class Xterm {
document.title = this.title; document.title = this.title;
break; break;
case Command.SET_PREFERENCES: case Command.SET_PREFERENCES:
console.log('[Xterm] Received SET_PREFERENCES, ptyOutputReceived:', this.ptyOutputReceived);
if (!this.ptyOutputReceived) {
this.ptyOutputReceived = true;
console.log('[Xterm] SET_PREFERENCES: ttyd is now ready, attempting to execute attach command');
this.tryExecuteAttachCommand();
}
this.applyPreferences({ this.applyPreferences({
...this.options.clientOptions, ...this.options.clientOptions,
...JSON.parse(textDecoder.decode(data)), ...JSON.parse(textDecoder.decode(data)),
@@ -704,6 +837,12 @@ export class Xterm {
} }
private stripAnsi(input: string): string { private stripAnsi(input: string): string {
return input.replace(/\u001B\[[0-9;?]*[ -\/]*[@-~]/g, '').replace(/\u0007/g, ''); // CSI: ESC [ ... command
// OSC: ESC ] ... (BEL or ESC \)
// BEL: \u0007
return input
.replace(/\u001B\][^\u0007\u001B]*(?:\u0007|\u001B\\)/g, '') // OSC ... BEL or ST
.replace(/\u001B\[[0-9;?]*[ -\/]*[@-~]/g, '') // CSI
.replace(/\u0007/g, ''); // stray BEL
} }
} }

View File

@@ -18,7 +18,7 @@ LIBWEBSOCKETS_VERSION="${LIBWEBSOCKETS_VERSION:-4.3.3}"
build_zlib() { build_zlib() {
echo "=== Building zlib-${ZLIB_VERSION} (${TARGET})..." echo "=== Building zlib-${ZLIB_VERSION} (${TARGET})..."
curl -fSsLo- "https://devstar.cn/alexios/build-deps/releases/download/v1.0/zlib-${ZLIB_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}" curl -fSsLo- "https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}"
pushd "${BUILD_DIR}"/zlib-"${ZLIB_VERSION}" pushd "${BUILD_DIR}"/zlib-"${ZLIB_VERSION}"
env CHOST="${TARGET}" ./configure --static --archs="-fPIC" --prefix="${STAGE_DIR}" env CHOST="${TARGET}" ./configure --static --archs="-fPIC" --prefix="${STAGE_DIR}"
make -j"$(nproc)" install make -j"$(nproc)" install
@@ -27,7 +27,7 @@ build_zlib() {
build_json-c() { build_json-c() {
echo "=== Building json-c-${JSON_C_VERSION} (${TARGET})..." echo "=== Building json-c-${JSON_C_VERSION} (${TARGET})..."
curl -fSsLo- "https://devstar.cn/alexios/build-deps/releases/download/v1.0/json-c-${JSON_C_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}" curl -fSsLo- "https://s3.amazonaws.com/json-c_releases/releases/json-c-${JSON_C_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}"
pushd "${BUILD_DIR}/json-c-${JSON_C_VERSION}" pushd "${BUILD_DIR}/json-c-${JSON_C_VERSION}"
rm -rf build && mkdir -p build && cd build rm -rf build && mkdir -p build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \ cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \
@@ -43,7 +43,7 @@ build_json-c() {
build_mbedtls() { build_mbedtls() {
echo "=== Building mbedtls-${MBEDTLS_VERSION} (${TARGET})..." echo "=== Building mbedtls-${MBEDTLS_VERSION} (${TARGET})..."
curl -fSsLo- "https://devstar.cn/alexios/build-deps/releases/download/v1.0/mbedtls-${MBEDTLS_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}" curl -fSsLo- "https://github.com/ARMmbed/mbedtls/archive/v${MBEDTLS_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}"
pushd "${BUILD_DIR}/mbedtls-${MBEDTLS_VERSION}" pushd "${BUILD_DIR}/mbedtls-${MBEDTLS_VERSION}"
rm -rf build && mkdir -p build && cd build rm -rf build && mkdir -p build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \ cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \
@@ -57,7 +57,7 @@ build_mbedtls() {
build_libuv() { build_libuv() {
echo "=== Building libuv-${LIBUV_VERSION} (${TARGET})..." echo "=== Building libuv-${LIBUV_VERSION} (${TARGET})..."
curl -fSsLo- "https://devstar.cn/alexios/build-deps/releases/download/v1.0/libuv-v${LIBUV_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}" curl -fSsLo- "https://dist.libuv.org/dist/v${LIBUV_VERSION}/libuv-v${LIBUV_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}"
pushd "${BUILD_DIR}/libuv-v${LIBUV_VERSION}" pushd "${BUILD_DIR}/libuv-v${LIBUV_VERSION}"
./autogen.sh ./autogen.sh
env CFLAGS=-fPIC ./configure --disable-shared --enable-static --prefix="${STAGE_DIR}" --host="${TARGET}" env CFLAGS=-fPIC ./configure --disable-shared --enable-static --prefix="${STAGE_DIR}" --host="${TARGET}"
@@ -83,7 +83,7 @@ EOF
build_libwebsockets() { build_libwebsockets() {
echo "=== Building libwebsockets-${LIBWEBSOCKETS_VERSION} (${TARGET})..." echo "=== Building libwebsockets-${LIBWEBSOCKETS_VERSION} (${TARGET})..."
curl -fSsLo- "https://devstar.cn/alexios/build-deps/releases/download/v1.0/libwebsockets-${LIBWEBSOCKETS_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}" curl -fSsLo- "https://github.com/warmcat/libwebsockets/archive/v${LIBWEBSOCKETS_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}"
pushd "${BUILD_DIR}/libwebsockets-${LIBWEBSOCKETS_VERSION}" pushd "${BUILD_DIR}/libwebsockets-${LIBWEBSOCKETS_VERSION}"
sed -i 's/ websockets_shared//g' cmake/libwebsockets-config.cmake.in sed -i 's/ websockets_shared//g' cmake/libwebsockets-config.cmake.in
sed -i 's/ OR PC_OPENSSL_FOUND//g' lib/tls/CMakeLists.txt sed -i 's/ OR PC_OPENSSL_FOUND//g' lib/tls/CMakeLists.txt
@@ -134,7 +134,7 @@ build() {
ALIAS="$2" ALIAS="$2"
STAGE_DIR="${STAGE_ROOT}/${TARGET}" STAGE_DIR="${STAGE_ROOT}/${TARGET}"
BUILD_DIR="${BUILD_ROOT}/${TARGET}" BUILD_DIR="${BUILD_ROOT}/${TARGET}"
MUSL_CC_URL="https://devstar.cn/alexios/build-deps/releases/download/v1.0" MUSL_CC_URL="https://github.com/tsl0922/musl-toolchains/releases/download/2021-11-23"
COMPONENTS="1" COMPONENTS="1"
SYSTEM="Linux" SYSTEM="Linux"

32610
src/html.h generated

File diff suppressed because it is too large Load Diff