资讯详情

银河麒麟离线源码编译SVN 1.8.14与svnserve部署避坑

📅 2026/10/24 12:30:26 | 华诺云谱 👁 阅读
银河麒麟离线源码编译SVN 1.8.14与svnserve部署避坑
简介这份文档面向在银河麒麟操作系统上部署版本控制服务的技术人员聚焦源码方式安装Subversion及其依赖环境适合需要离线编译、内网部署或按步骤排查安装问题的运维与开发人员参考。压缩包内共1个docx文件约202KB篇幅紧凑便于随项目归档和查阅。目前已有2798人学习说明其在国产化系统运维场景中具有一定参考价值。内容围绕apr、apr-util、SQLite与Subversion的编译安装展开覆盖环境变量配置、版本库创建、用户与权限设置、svnserve服务启动以及Windows客户端访问和开机自启等收尾环节并穿插配置项说明与常见注意事项。读者可据此梳理银河麒麟下SVN环境搭建的完整流程快速定位编译依赖、权限配置和服务启动中的易错点。1. 银河麒麟上源码编译 SVN老版本 1.8.14 为什么反而更省事某公司内网要做版本管理服务器是银河麒麟外网只开了镜像系统源里的 subversion 版本和桌面端 TortoiseSVN 对不上提交时直接提示工作副本版本过高。折腾一圈后发现最省事的路径不是升级客户端而是源码编译一套固定版本的 subversion 和 svnserve把服务端版本钉死。这套东西解决的是「内网无外网、系统源版本不可控」场景下自建版本库的问题适合手里有几台麒麟机器、要给一个小团队开 trunk/branches、又不想引入额外中间件的人。下面按依赖、编译、建库、权限、排错、自启的顺序把实际走通的流程摊开写命令都是能直接抄的。2. apr、apr-util 与 sqlite 的编译顺序三个包谁先谁后决定成败源码编译 SVN 最容易卡住的地方不是 SVN 本身而是三个依赖包的顺序和路径。subversion 1.8.14 依赖 APRApache Portable Runtime、APR-UTIL 和 SQLite三者有严格的先后关系APR 必须先装APR-UTIL 编译时要通过--with-apr找到 APR 的安装目录而 subversion 的 configure 又要同时找到这两个的 config 脚本。顺序错了报错信息往往很含糊只告诉你「not found」不会告诉你是哪个路径写错了。2.1 离线环境下的源码包准备与版本核对内网机器没法直接dnf install源码包要提前在能上网的机器上下好再拷进麒麟环境。老版本在 Apache 的归档站上比在镜像站上更稳因为镜像站只保留当前版本1.6.x 这类老包在镜像里经常已经下架。我一般统一放到/home/dmdba/svn/下一个目录管到底后面编译、排错、回滚都不用到处找文件。# 以 root 操作源码统一放在 /home/dmdba/svn 下避免文件散落 mkdir -p /home/dmdba/svn cd /home/dmdba/svn # apr 与 apr-util 从 Apache 归档站取老版本在归档里长期存在 tar -zxvf apr-1.6.5.tar.gz tar -zxvf apr-util-1.6.1.tar.gz tar -zxvf subversion-1.8.14.tar.gz # sqlite amalgamation 是 zip 包解压后只有 sqlite3.c 和 sqlite3.h 两个核心文件 unzip sqlite-amalgamation-3071501.ziptar -zxvf里的z表示 gzip 解压x是解包v输出文件列表方便确认包没坏f指定文件名。unzip不带参数会解到当前目录解出来的目录名是sqlite-amalgamation-3071501这个目录名后面要用到别随手改。版本对应关系建议先核对一遍再动手这套组合是 1.8.x 分支上比较稳的一组组件版本作用安装前缀apr1.6.5跨平台运行时库SVN 的内存池、文件操作都走它/usr/local/aprapr-util1.6.1APR 的扩展库XML、数据库抽象层/usr/local/apr-utilsqlite amalgamation3071501即 3.7.15.1SVN 版本库的底层存储引擎编进 SVN不单独装subversion1.8.14服务端与命令行客户端/usr/local/svn拷贝进内网后先做一次完整性校验归档站每个包旁边都有.md5文件比对不上就别往下走了编译到一半报「gzip: stdin: unexpected end of file」多半就是包没传完整。cd /home/dmdba/svn md5sum apr-1.6.5.tar.gz apr-util-1.6.1.tar.gz subversion-1.8.14.tar.gz # 与同目录下 .md5 文件里的值逐行比对不一致就重新拷贝提示麒麟环境如果是最小化安装gcc、make、unzip可能都没有先确认gcc --version和make --version有输出再往下走。2.2 apr 与 apr-util 的 configure 参数与安装验证APR 的编译是最简单的一步但--prefix一定要想清楚后面 apr-util 和 subversion 都要引用这个路径中途改前缀等于前面的活白干。我固定用/usr/local/apr不带尾部斜杠带斜杠在某些 configure 版本里会拼出双斜杠路径。cd /home/dmdba/svn/apr-1.6.5 ./configure --prefix/usr/local/apr make -j$(nproc) make install--prefix决定make install把库、头文件、apr-1-config脚本放到哪make -j$(nproc)用满 CPU 核数并行编译麒麟机器核少的话去掉-j也行差别只在耗时make install要 root 权限因为目标目录在/usr/local下。装完立刻验证别等后面报错再回头查/usr/local/apr/bin/apr-1-config --version ls /usr/local/apr/include/apr-1/apr.hapr-1-config是给下游包用的探测脚本apr-util 和 subversion 的 configure 都会调用它拿编译参数。这个脚本不在后面一定失败。接着编 apr-util关键是--with-apr必须指向刚装好的/usr/local/apr而不是源码目录cd /home/dmdba/svn/apr-util-1.6.1 ./configure --prefix/usr/local/apr-util --with-apr/usr/local/apr make -j$(nproc) make install # 验证 apr-util 的探测脚本也装好了 /usr/local/apr-util/bin/apu-1-config --version--with-apr写成源码目录../apr-1.6.5是最常见的错误configure 阶段可能不报错但编译到链接时找不到libapr-1.so报错信息里一堆 undefined reference看着像代码问题其实是路径问题。如果麒麟系统上缺 expat 相关头文件apr-util 的 configure 会提示找不到 XML 解析器常见做法是装expat-devel或者加--with-expatbuiltin让 apr-util 用自带的 expat 源码编内网不方便装包时后者更省事。2.3 sqlite amalgamation 放进源码树的位置与理由SQLite 这块是 subversion 1.8 编译里最容易翻车的一环。subversion 的构建脚本约定在源码树根目录下找sqlite-amalgamation/目录里面放sqlite3.c。它不通过系统libsqlite3链接而是把这个 C 文件直接编进libsvn_subr目的是版本可控、避免和系统里其他程序的 SQLite 符号冲突。所以不能只把 zip 解压了就完事得把文件放到约定的位置。cd /home/dmdba/svn # subversion 1.8 的构建脚本只认源码树里的 sqlite-amalgamation 目录 mkdir -p subversion-1.8.14/sqlite-amalgamation cp sqlite-amalgamation-3071501/sqlite3.c subversion-1.8.14/sqlite-amalgamation/ cp sqlite-amalgamation-3071501/sqlite3.h subversion-1.8.14/sqlite-amalgamation/ # 确认位置正确文件名必须是 sqlite3.c大小写都不能错 ls -l subversion-1.8.14/sqlite-amalgamation/mkdir -p的-p保证父目录不存在时一起建拷贝时只认sqlite3.c这个名字把整个目录改名成sqlite-amalgamation放在源码树里也行效果一样。sqlite3.h一起拷进去不是必须的但排错时有用编译报缺头文件时能第一时间确认是不是这里的问题。另一种做法是 configure 时用--with-sqlite/usr/local/sqlite指向单独编译的 SQLite适合系统里已经有匹配版本的场景。但在麒麟上系统自带的libsqlite3版本往往偏新或偏旧和 subversion 1.8 的 API 不一定对得上编译期不报错、运行期svnadmin create报 schema 异常的情况我见过不止一次。离线环境下用 amalgamation 是后悔药最少的选择多拷两个文件省掉一晚上的排查。3. Subversion 本体编译从 configure 摘要到 svnserve --version 的四个检查点依赖装完subversion 的编译反而快了。这一步的核心不是敲命令而是看懂 configure 最后输出的摘要以及make install之后库文件到底落在哪。很多人卡在「装完了svnserve --version却报找不到库」问题基本都出在这一章。3.1 configure 参数逐条拆解与摘要解读编译参数不多但每一个都对应一个依赖路径写错一个就前功尽弃。下面这条命令是实际跑通的版本cd /home/dmdba/svn/subversion-1.8.14 ./configure \ --prefix/usr/local/svn \ --with-apr/usr/local/apr \ --with-apr-util/usr/local/apr-util--prefix/usr/local/svn是 SVN 的安装根二进制在bin/库在lib/--with-apr和--with-apr-util分别指向前面两个依赖的安装前缀configure 会去这两个目录下找apr-1-config和apu-1-config。三个参数之间用反斜杠换行实际执行时是一整行复制到终端里不会出问题。configure 跑完最后会打印一段摘要重点看这几行APR和APR-UTIL的版本号是否显示出来、SQLite是否显示为internal说明用的是源码树里的 amalgamation、serf和ssl的状态。如果 SQLite 那一行显示not found回头检查 2.3 里的目录名和文件名如果 APR 显示not found基本是--with-apr路径写错了。常见追加参数有两个要让svn客户端能拉https://的仓库加--with-ssl前提是系统有openssl-devel只在内网走svn://协议的话可以不加减少一层依赖。另一个是--with-zlib压缩传输用系统有zlib-devel就加上没有也不影响svn://的基本使用。内网环境我一般只加--with-ssl其余保持默认参数越少出问题时变量越少。3.2 make install 之后的目录布局与动态库处理编译和安装命令本身没有悬念关键是装完之后要知道东西在哪make -j$(nproc) make install装完之后/usr/local/svn/bin/下会多出一组命令常用的是这几个命令用途svn命令行客户端拉取、提交、查看日志svnadmin建库、备份、校验版本库svnserve轻量级服务端走 svn:// 协议svnlook直接查看版本库内容排错时很有用svnsync版本库镜像同步库文件在/usr/local/svn/lib/下是一组libsvn_*.so.1。问题来了svnserve启动时要加载这些库以及/usr/local/apr/lib和/usr/local/apr-util/lib下的 APR 库。默认情况下动态链接器只认/lib、/usr/lib这些标准路径/usr/local下的子目录不在搜索范围里于是就会出现「编译装完了一执行就报 cannot open shared object file」。先确认依赖有没有断ldd /usr/local/svn/bin/svnserve | grep not found如果有输出说明有库找不到。解决办法是把三个库目录登记到动态链接器配置里而不是靠临时export LD_LIBRARY_PATHcat /etc/ld.so.conf.d/svn.conf EOF /usr/local/svn/lib /usr/local/apr/lib /usr/local/apr-util/lib EOF # 让新配置立即生效 ldconfig # 再次检查这次应该没有 not found 输出 ldd /usr/local/svn/bin/svnserve | grep not found/etc/ld.so.conf.d/下的.conf文件会被ldconfig统一读取写在这里是全局生效、重启不丢LD_LIBRARY_PATH只对当前 shell 有效换个终端或者被 systemd 拉起就失效属于典型的「本地好的、上线就挂」。三个路径一行一个别用冒号拼在一行ld.so.conf的格式是按行解析的。3.3 环境变量写 /etc/profile 还是 profile.d一个容易漏的差异svnserve --version要在任意目录下都能敲就得把/usr/local/svn/bin加进 PATH。直接改/etc/profile是原始做法能在登录 shell 里生效但有两个隐患一是文件越改越长多人维护时容易冲突二是某些非登录 shell比如ssh host command这种不读/etc/profile命令就找不到。更规范的做法是单独放一个/etc/profile.d/svn.shcat /etc/profile.d/svn.sh EOF # 只追加 SVN 的 bin 目录保留系统原有 PATH export PATH$PATH:/usr/local/svn/bin EOF chmod x /etc/profile.d/svn.sh # 当前已登录的 shell 需要手动 source 一次新开的终端会自动加载 source /etc/profile.d/svn.shexport不能省只写PATH$PATH:...在当前 shell 里看着有效子进程拿不到chmod x不是必须的但加上没坏处某些发行版的 profile 加载逻辑会跳过没有执行位的脚本。source只影响当前终端已经开着的其他窗口要各自执行一次或者退出重登。验证分三步缺一步都可能误判# 1. 命令能否找到 which svnserve # 2. 版本号是否正常输出同时验证动态库加载没问题 svnserve --version # 3. 新开一个终端再敲一次确认 profile.d 生效which svnserve输出/usr/local/svn/bin/svnserve才算 PATH 配对了svnserve --version除了打印版本还会列出支持的协议svn://、svnssh://如果只有前者没有后者说明编译时 SSH 相关依赖没找到内网自用影响不大。第三步最容易漏很多人当前终端好了就以为完事结果运维同事登录上去发现命令不存在又回来查半天。4. 版本库与权限三件套svnadmin create 之后的三个配置文件SVN 服务端起不来十次里有七次不是二进制的问题是conf/下那三个配置文件的问题。svnserve.conf管匿名访问和认证开关passwd管用户密码authz管路径权限。三个文件各管一摊但互相引用改错一个就可能出现「能连上但一直弹认证」或者「认证过了但提交被拒」这类玄学现象。4.1 svnserve.conf 的最小可用写法与 realm 的作用先建库。版本库根目录我选/home/svn下面每个项目一个子目录svnserve -r /home/svn一次带起所有项目后面加项目不用重启服务# 版本库根目录 mkdir -p /home/svn # 具体项目目录-p 保证父目录一起建 mkdir -p /home/svn/project # 把 project 目录初始化为 SVN 版本库 svnadmin create /home/svn/project # 建库后 conf 目录下会生成三个配置文件 ls -l /home/svn/project/conf/svnadmin create执行完目录里会出现conf/、db/、hooks/、locks/、format这几项db/是真正的数据存储conf/是配置。接下来编辑svnserve.conf最小可用配置只有五行[general] anon-access none auth-access write password-db passwd authz-db authz realm /home/svn/projectanon-access none表示未认证用户什么都干不了这是内网版本库该有的默认值auth-access write给认证用户读写权限password-db和authz-db分别指向同目录下的passwd和authz写相对路径就行realm是认证域客户端会按 realm 缓存凭据不写的话默认用版本库路径多个项目共用一套账号时建议显式写清楚否则切换项目时客户端可能拿着旧凭据反复弹窗。注意[general]这一行必须顶格前面不能有空格文件首行也不能留空行。svnserve 的配置解析器对缩进很敏感多一个空格就报「Invalid config file」或者直接忽略整段配置表现为匿名可以读、认证用户反而被拒。原文里提到「首行不可以留空要顶行」这是血泪经验不是格式洁癖。用vi编辑时按i进入插入模式改完ESC再:wq保存别用带自动缩进的编辑器插件很容易在[general]前插一个制表符。4.2 passwd 与 authz 的群组授权路径到底相对谁passwd文件管账号格式很简单一个用户一行[users] admin 123456[users]段名不能改用户名和密码之间用等号等号两边可以有空格但别留多余空白字符密码末尾带空格是最隐蔽的坑登录时怎么输都不对。这里用弱密码只是为了演示实际部署一定要换掉并且把文件权限收紧到 600passwd是明文存储同机器上有读权限的人都能看到。authz文件管权限群组写法能省很多重复配置[groups] g_admin admin [/] g_admin rw * [groups]段定义群组g_admin包含admin一个用户多个用户用逗号分隔[/]表示版本库根目录g_admin rw给这个群组读写权限* 表示除上面列出的群组外其他所有人无任何权限等号后面留空就是「无权限」不是「继承」。这里有个特别容易理解错的地方authz里的/是版本库根不是svnserve -r指定的那个目录。当服务用svnserve -d -r /home/svn启动、客户端访问svn://ip/project时authz里的/对应的是project这个版本库的根而不是/home/svn。如果要控制版本库内部的子目录写[/trunk]、[/branches]这种形式。把/当成/home/svn来写[/project]结果就是权限怎么配都不对客户端不是 403 就是能读不能写。4.3 svnserve 启动参数与客户端连通验证配置改完启动服务# -d 后台运行-r 指定版本库根目录注意路径只到 /home/svn svnserve -d -r /home/svn # 确认进程在 ps -ef | grep [s]vnserve # 确认 3690 端口在监听 ss -lntp | grep 3690-d让 svnserve 以守护进程方式跑在后台前台不占终端-r是版本库根客户端 URL 里的第一段路径会拼在它后面所以只写到/home/svn不能写成/home/svn/project否则访问路径就变成svn://ip/project/project。ps -ef | grep [s]vnserve里方括号是为了排除 grep 自己那一行看输出更干净。本机先自测排除网络因素svn list svn://127.0.0.1/project --username admin --password 123456能列出空目录说明服务端配置、认证、权限三件事都通了。如果这一步报Authorization failed问题在authz的路径或passwd的账号如果报Unable to connect问题在进程或端口。验证点命令期望结果进程存在ps -ef | grep svnserve有一条 svnserve 进程端口监听ss -lntp | grep 3690LISTEN 状态本机认证svn list svn://127.0.0.1/project列出目录内容远端连通客户端连 svn://服务器IP/project弹认证框输入后能浏览远端连不上先查防火墙麒麟默认可能开着 firewalld# 放通 3690 端口--permanent 保证重启后仍生效 firewall-cmd --permanent --add-port3690/tcp firewall-cmd --reload firewall-cmd --list-ports--permanent不加的话规则只在当前运行期有效重启就没了这是另一个常见误解。--reload让规则立即生效但不断开现有连接。客户端地址写成svn://服务器IP/project注意是双斜杠加 IP 再加项目名少一个斜杠或者多写一层路径都会连到错误的位置。5. 避坑与排查麒麟上装 SVN 常见的五个翻车现场这一章按「现象 → 原因 → 解决」整理都是实际踩过的顺序按出现频率从高到低。排错时建议从下往上倒推先确认进程和端口再看配置最后才怀疑编译。5.1 编译期找不到 apr-util 与 sqlite3.h现象一configure 报APR-UTIL not found但 apr-util 明明装过了。原因基本是--with-apr-util指向了源码目录或者 apr-util 装到了非默认前缀而参数没跟着改。configure 找的是apu-1-config这个脚本不是libaprutil-1.so。 解决先跑/usr/local/apr-util/bin/apu-1-config --version确认脚本存在再检查 subversion 的 configure 参数里--with-apr-util是不是写的/usr/local/apr-util。如果 apr-util 装在了别处把参数改成实际路径别用软链接糊弄configure 会解析脚本里的绝对路径。现象二configure 报An appropriate version of sqlite could not be found。原因是源码树里的sqlite-amalgamation/sqlite3.c不存在或者目录名拼错比如写成sqlite-amalgamation-3071501。 解决ls subversion-1.8.14/sqlite-amalgamation/sqlite3.c确认文件在目录名必须是sqlite-amalgamation文件名必须是sqlite3.c大小写敏感。改完目录结构要重新跑 configuremakefile 是 configure 生成的光改文件不重跑没用。现象三make 阶段报gcc: command not found或编译到一半被 OOM Killer 杀掉。原因是麒麟最小化安装没带编译工具链或者make -j开的并行数超过了内存承受能力。 解决先gcc --version确认工具链缺就装gcc、make、glibc-devel内存小的机器把-j$(nproc)改成-j2甚至去掉-j单线程编慢一点但不会中途崩。5.2 运行期配置首行、权限与端口现象四服务起来了客户端一直弹认证框输对密码也进不去。原因通常是svnserve.conf文件首行或段名前有空格解析器把整段[general]忽略了匿名访问策略回落到默认值认证配置根本没生效另一个可能是passwd里密码尾部带了空格。 解决sed -n 1,10p /home/svn/project/conf/svnserve.conf看前几行有没有缩进有就删掉cat -A passwd看行尾有没有$之外的空白字符。改完必须重启 svnserve配置不会热加载。现象五客户端能浏览但提交报Permission denied服务端日志里是Cant open file db/txn-current-lock。原因是版本库目录的属主和运行 svnserve 的用户不一致。用 root 建库、用普通用户起服务或者反过来都会导致写锁文件失败。这是权限问题不是authz配置问题很多人会往authz上查方向就错了。 解决ps -ef | grep svnserve看运行用户ls -ld /home/svn/project/db看目录属主用chown -R 同一用户:同一组 /home/svn/project统一然后重启服务。日常操作也别用 root 直接往版本库里提交混用身份是这类问题的根源。补充一条端口问题本机svn list通、远端连不上九成是防火墙没放通 3690或者-r的路径写多了一层。先用ss -lntp | grep 3690确认监听地址是0.0.0.0而不是127.0.0.1再看防火墙规则。svnserve 默认监听所有网卡如果只监听本地检查启动命令里有没有多写--listen-host。6. 开机自启与长期维护把 svn.sh 换成 systemd 单元用rc.local加一个svn.sh脚本是最原始的做法能跑但有几个现实问题rc.local在新版系统上默认没有执行权限、脚本里如果依赖 PATH 会因为环境没加载而失败、服务挂了没有自动拉起。麒麟上更稳的做法是写一个 systemd 单元把启动路径写死成绝对路径彻底绕开环境变量的问题。先确认svnserve支持前台运行1.8 版本带--foreground参数/usr/local/svn/bin/svnserve --help | grep foreground有输出就按下面的单元文件写Typesimple配合前台运行systemd 能直接托管进程停止、重启、看状态都规范# /etc/systemd/system/svnserve.service [Unit] DescriptionSubversion Serve Afternetwork.target [Service] Typesimple # 绝对路径不依赖 /etc/profile 里的 PATH ExecStart/usr/local/svn/bin/svnserve --foreground -r /home/svn Restarton-failure RestartSec3 [Install] WantedBymulti-user.targetAfternetwork.target保证网络就绪后再起服务--foreground让 svnserve 不 fork进程直接由 systemd 管Restarton-failure是rc.local方案给不了的进程异常退出 3 秒后自动拉起WantedBymulti-user.target决定systemctl enable时的启动级别。如果你的版本不支持--foreground退回-d并把Type改成forking同时用ExecStop/usr/bin/pkill -f svnserve收尾但不如前台方案干净。启用和验证一条龙systemctl daemon-reload systemctl enable --now svnserve systemctl status svnserve --no-pager # 重启机器后再验一次这一步别省 rebootdaemon-reload在改完单元文件后必须执行否则 systemd 读的还是旧配置enable --now同时做开机自启和立即启动status看Active: active (running)才算成功。重启验证是唯一能证明自启真的生效的手段我在这个环节翻过车单元文件里的路径写成了相对路径手动systemctl start一切正常重启后直接失败journalctl -u svnserve里只有一行No such file or directory。最后给一个日常巡检的习惯每次改完svnserve.conf、passwd、authz先svnadmin verify /home/svn/project确认版本库本身没坏再systemctl restart svnserve最后用svn list走一遍认证。三步都过再通知同事使用比等别人报「提交不了」再回头查要省事得多。从那以后我每次动配置都强制走这三步再没出现过改完忘了重启、同事对着旧配置排查半天的情况。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑