bhrs
Published on 2026-04-28 / 33 Visits
0

RustDesk自编译教程

本文基于文章:RustDesk源码简单修复环境变量 让小白也能使用Github轻松编译(作者:鼠标迁徙)修改和优化

客户端编译

早期,官方 github 项目是允许配置变量,直接编译的!后来,作者出于被过分滥用的考虑,删除了变量调用!鼠标也出过相应教程,修改源码,实现服务器等信息内置!操作起来,虽说没有什么难度,但是对于小白来说,却也不是怎么友好!这次好了,无需本地环境,无需复杂的 git 命令,全程在 web 网页操作!

Fork 项目

登录 Github 账号,访问 rustdesk官方项目 仓库,将客户端项目 fork 到我们自己的仓库;同时,访问子模块,并将子模块也一并 fork 到我们的仓库。

源码修改

fork 到我们仓库的源码,我们有三个地方需要修改,分别是子模块地址、工作流变量读取、配置文件变量调用。

子模块地址修改

该文件位于主仓库目录下的.gitmodules文件,点击查看该文件,点击右上角铅笔图标(Edit this file)进入编辑模式,修改https://github.com/rustdesk/hbb_common,将rustdesk替换为你的用户名,也就我们 fork 后的子模块仓库地址。修改完后点击右上角Commit changes按钮,在Commit message填写下备注,譬如:修改子模块地址,最后点击Commit changes保存。

工作流变量读取修改

该文件位于主仓库目录下.github/workflows/flutter-build.yml文件,编辑方法同上,在代码的第 49 行(env:下级的最后)添加如下代码:

  RS_PUB_KEY: "${{secrets.RS_PUB_KEY}}"
  RENDEZVOUS_SERVER: "${{secrets.RENDEZVOUS_SERVER}}"
  API_SERVER: "${{secrets.API_SERVER}}"

api地址变量调用

默认api地址为http://<RENDEZVOUS_SERVER>:21114如无需变化此步可忽略

该文件位于主模块仓库目录src/common.rs文件,Ctrl+ F 搜索定位如下代码行:(如果过程中无法修改,可切换到 master 分支)

let s0 = get_custom_rendezvous_server(custom);

搜索结果替换为如下代码:

let api = option_env!("API_SERVER").unwrap_or_default();
    if !api.is_empty() {
        return api.into();
    }
    let s0 = get_custom_rendezvous_server(custom);

配置文件变量调用

该文件位于子模块仓库目录src/config.rs文件,Ctrl+ F 搜索定位如下代码行:(如果过程中无法修改,可切换到 main 分支)

pub const RS_PUB_KEY: &str = "OeVuKk5nlHiXp+APNn0Y3pC1Iwpwn44JGqrQCsWqmBw=";

搜索结果替换为如下代码:

pub const PUBLIC_RS_PUB_KEY: &str = "OeVuKk5nlHiXp+APNn0Y3pC1Iwpwn44JGqrQCsWqmBw=";
pub const RS_PUB_KEY: &str = match option_env!("RS_PUB_KEY") {Some(key) if !key.is_empty() => key,
  _ => PUBLIC_RS_PUB_KEY,
};

接着,Ctrl+ F 搜索定位如下代码行:

pub static ref PROD_RENDEZVOUS_SERVER: RwLock<String> = RwLock::new("".to_owned());

搜索结果替换为如下代码:

pub static ref PROD_RENDEZVOUS_SERVER: RwLock<String> = RwLock::new(match option_env!("RENDEZVOUS_SERVER") {Some(key) if !key.is_empty() => key,
      _ => "",
    }.to_owned());

粘贴后的代码,我们可以使用 Tab 键及 Shift+Tab 键,来调整代码缩进格式。这次代码提交后,我们需要记录下本次提交的 hash 值(网址的最后),后面会用到!

修改 commit 指针

虽然我们修改了子模块的的地址,但是它链接的是之前的 commit,点进去你会发现,我们之前修改子模块的config.rs文件,根本没生效!所以,我们要修改 commit 指针,也就是指向我们刚刚修改的子模块 commit。

如何修改?还是将项目克隆到本地?用 git 重新提交?小白抗议,这太繁琐,太麻烦!跟着我操作,超级简单,网页也能修改 commit 指针!

创建 Github token

依次点击:右上角头像→Settings→Developer setting→Personal access tokens→Tokens (classic),生成新token:Generate new token→Generate new token (classic),Note这里随意填写,勾选repo,其他默认即可,最后点击Generate token,保存 token 备用!

修改 commit 指针

主仓库界面快捷键Ctrl+Shift+I打开浏览器控制台,将如下代码粘贴到控制台:

// 替换为您的实际信息
const owner = '用户名'; // 替换为实际的 用户名
const repo = 'rustdesk'; // 替换为实际的 主仓库名
const newCommitHash = 'commit hash 值'; // 替换为实际的 commit hash
const branch = 'master'; // 或 'main',根据您的仓库
const submodulePath = 'libs/hbb_common';

async function updateSubmodule() {
  try {
    // 获取 GitHub Token
    const token = prompt('请输入您的 GitHub Personal Access Token (需要 repo 权限):');
    if (!token) {
      alert('需要 Token 才能继续');
      return;
    }

    const headers = {
      'Authorization': `token ${token}`,  // 修复:模板字符串语法
      'Content-Type': 'application/json',
      'Accept': 'application/vnd.github.v3+json'
    };

    console.log('1. 获取分支引用...');

    // 1. 获取当前分支引用
    const refResponse = await fetch(`https://api.github.com/repos/${owner}/${repo}/git/refs/heads/${branch}`, { headers: headers });

    if (!refResponse.ok) {
      throw new Error(`获取分支引用失败: ${refResponse.status} ${refResponse.statusText}`);
    }

    const refData = await refResponse.json();
    const currentCommitSha = refData.object.sha;
    console.log('当前提交 SHA:', currentCommitSha);

    // 2. 获取提交对象
    console.log('2. 获取提交对象...');
    const commitResponse = await fetch(`https://api.github.com/repos/${owner}/${repo}/git/commits/${currentCommitSha}`, { headers: headers });

    if (!commitResponse.ok) {
      throw new Error(`获取提交对象失败: ${commitResponse.status} ${commitResponse.statusText}`);
    }

    const commitData = await commitResponse.json();
    const treeSha = commitData.tree.sha;
    console.log('当前树 SHA:', treeSha);

    // 3. 创建新树
    console.log('3. 创建新树...');
    const treeResponse = await fetch(`https://api.github.com/repos/${owner}/${repo}/git/trees`, {
      method: 'POST',
      headers: headers,
      body: JSON.stringify({
        base_tree: treeSha,
        tree: [
          {
            path: submodulePath,
            mode: '160000', // 子模块的特殊模式
            type: 'commit',
            sha: newCommitHash
          }
        ]
      })
    });

    if (!treeResponse.ok) {
      const errorText = await treeResponse.text();
      throw new Error(`创建树失败: ${treeResponse.status} ${treeResponse.statusText} - ${errorText}`);
    }

    const treeData = await treeResponse.json();
    console.log('新树 SHA:', treeData.sha);

    // 4. 创建新提交
    console.log('4. 创建新提交...');
    const newCommitResponse = await fetch(`https://api.github.com/repos/${owner}/${repo}/git/commits`, {
      method: 'POST',
      headers: headers,
      body: JSON.stringify({
        message: `Update ${submodulePath} submodule to ${newCommitHash.substring(0, 8)}`,  // 修复:模板字符串
        tree: treeData.sha,
        parents: [currentCommitSha]
      })
    });

    if (!newCommitResponse.ok) {
      const errorText = await newCommitResponse.text();
      throw new Error(`创建提交失败: ${newCommitResponse.status} ${newCommitResponse.statusText} - ${errorText}`);
    }

    const newCommitData = await newCommitResponse.json();
    console.log('新提交 SHA:', newCommitData.sha);

    // 5. 更新分支引用
    console.log('5. 更新分支引用...');
    const updateRefResponse = await fetch(`https://api.github.com/repos/${owner}/${repo}/git/refs/heads/${branch}`, {
      method: 'PATCH',
      headers: headers,
      body: JSON.stringify({
        sha: newCommitData.sha,
        force: false
      })
    });

    if (!updateRefResponse.ok) {
      const errorText = await updateRefResponse.text();
      throw new Error(`更新引用失败: ${updateRefResponse.status} ${updateRefResponse.statusText} - ${errorText}`);
    }

    console.log('子模块更新成功!');
    alert(`✅ 子模块更新成功!\n新提交: ${newCommitData.sha.substring(0, 8)}`);  // 修复:模板字符串和换行符

  } catch (error) {
    console.error('错误:', error);
    alert(`❌ 更新失败: ${error.message}`);  // 修复:模板字符串
  }
}

// 执行函数
updateSubmodule();

以上代码,第 2.3.4 行分别修改为你实际的 gtihub 用户名、仓库名,以及之前让你保存的 commit hash 值,回车运行,会提示你输入 token,将我们刚获取的 token 填入,并点击确定!片刻,commit 指针就更改好了!我们可以点击子模块,测试config文件是否修改!

添加变量

项目主仓库,点击Settings→Actions secrets and variables→Actions。点击New repository secret分别添加如下变量:

API_SERVER          //API 变量(如保持默认则无需设置) 例:http:127.0.0.1:21114
RENDEZVOUS_SERVER   // 中继服务器变量 例:127.0.0.1
RS_PUB_KEY          // 服务端 KEY 变量 例:OeVuKk5nlHiXp+APNn0Y3pC1Iwpwn44JGqrQCsWqmBw=

运行工作流

变量添加好后,我们就可以编译了,也就是运行 Gtihub Actions 工作流。运行之前,要确定主仓库设置里:Actions→General最下面的Read and write permissions和Allow GitHub Actions to create and approve pull requests这两个选项是选中状态!

主仓库点击 <code>Actions</code>,查看更多,选中这个文件,点击这里开启工作流,再点击这里运行工作流,剩下就是耐心的等了!一个小时左右,就会编译完成!在你项目的 Releases 里,就可以下载对应系统的客户端了!