Win10 WSL安装HTK执行make all报esig_asc/esignal编译错误
问题根因
WSL默认搭载的新版Linux发行版(Ubuntu 20.04/22.04、Debian 11+)使用glibc 2.28及以上版本,和HTK 3.4.1稳定版存在两处原生兼容性冲突,和configure阶段添加-m64参数的操作无关:
- 旧版HTK代码中定义的
_BSD_SOURCE、_SVID_SOURCE功能宏已被新版glibc弃用,官方要求替换为_DEFAULT_SOURCE。宏失效后会触发头文件条件编译逻辑错乱,直接导致esignal.h第895行出现语法解析错误 - HTK封装的
_ISalnum等字符判断宏,依赖旧版glibc ctype头文件暴露的私有定义,新版glibc已经移除这部分直接对外暴露的私有宏,触发标识符未声明报错
修复步骤
1. 修正功能宏定义
首先修改源码根目录下的configure文件,搜索所有_BSD_SOURCE、_SVID_SOURCE相关的编译参数定义,将两个旧宏替换为_DEFAULT_SOURCE,对应代码段修改示例:
# 原代码 CFLAGS="$CFLAGS -D_BSD_SOURCE -D_SVID_SOURCE" # 修改后 CFLAGS="$CFLAGS -D_DEFAULT_SOURCE"
之前添加的-m64编译参数保留即可,无需删除。
随后打开HTKLib/esignal.h文件,定位到头部的宏定义区块,如果存在如下两行定义直接删除:
#define _BSD_SOURCE #define _SVID_SOURCE
在头文件所有#include语句之前,新增一行宏定义:
#define _DEFAULT_SOURCE 1
2. 替换_ISxxx系列宏实现
在HTKLib/esignal.h中定位到所有_IS开头的字符判断宏定义区块,将原有依赖glibc私有实现的定义,全部替换为标准ctype库调用版本,替换内容如下:
#define _ISalnum(c) isalnum((unsigned char)(c)) #define _ISalpha(c) isalpha((unsigned char)(c)) #define _ISupper(c) isupper((unsigned char)(c)) #define _ISlower(c) islower((unsigned char)(c)) #define _ISprint(c) isprint((unsigned char)(c)) #define _ISxdigit(c) isxdigit((unsigned char)(c)) #define _ISdigit(c) isdigit((unsigned char)(c)) #define _ISspace(c) isspace((unsigned char)(c)) #define _ISgraph(c) isgraph((unsigned char)(c))
注意:宏参数必须强转为unsigned char类型,否则处理扩展ASCII字符时会触发内存访问越界问题。
3. 清理中间文件重新编译
回到HTK源码根目录,执行命令清理之前编译失败生成的中间产物,再重新走配置、编译流程:
make distclean ./configure # 保持之前使用的配置参数不变即可 make all -j$(nproc)
如果编译过程中不再抛出esig_asc.c相关错误,即可继续执行make install完成部署。
有效性验证
编译完成后执行HInit -?,如果正常输出HTK工具的命令帮助信息,说明部署成功。
内容的提问来源于stack exchange,提问作者Ting Su
相关产品推荐
相关产品推荐

