内核编译答疑 - JackA1ltman/NonGKI_Kernel_Build_2nd GitHub Wiki

内核编译答疑

本页收录编译过程中的常见问题与解决思路。遇到报错时,建议优先完整阅读编译日志,真正的错误原因往往在 Error 2 这一行之上


编译准备期间

Q1:为什么提示 No such file or directory

分析:编译器无法在指定路径找到头文件(.h)或源文件(.c)。

解决

  • 检查文件路径是否正确
  • 若是系统头文件缺失,尝试安装对应依赖库,例如:
sudo apt install libssl-dev zlib1g-dev

Q2:提示 cannot open 且涉及 .gz 文件?

分析:编译所需的配置文件未生成,或曾执行过 make mrproper 导致配置被清除。

解决:重新运行 defconfig 命令生成配置文件:

make ARCH=arm64 O=out <your_defconfig>

编译错误(Error 2)

编译器与工具链兼容性

Q3:提示 unrecognized command line option

分析:当前工具链版本与内核代码要求不匹配(过旧或过新),导致某个编译选项无法被识别。

解决:检查 Makefile 中对应的编译器选项,并考虑升级或降级 GCC / Clang 版本。


Q4:提示 target emulation unknown

分析:链接器(ld)无法识别指定的仿真模式,通常是混用了 LLVM 和 GNU 工具链导致的。

解决:确认 LD 变量指向了正确工具链的链接器。使用 LLVM 时应设置:

LD=ld.lld

Q5:提示 assembler command failed with exit code 1

分析:汇编器报错,通常是 Clang 内部错误或版本不兼容。

解决:尝试更换其他版本的 Clang。


KernelSU 相关

Q6:提示 MODULE_IMPORT_NS(...) VFS_internal... 错误?

分析:KernelSU 官方版与 Non-GKI 内核或当前所用 Fork 分支存在不兼容。

解决

  • 官方版:尝试回退到旧版本,如 v0.9.5
  • Fork 版:切换到正确分支。以 SukiSU-Ultra 为例,Non-GKI 内核应使用 builtin 分支而非 main 分支

Clang 异常

Q7:提示 not found (required by clang)

分析:系统环境版本过低,无法支持当前版本的 Clang 运行。

解决:升级操作系统,建议使用 Ubuntu 22.04 或更高版本。


Q8:提示 Error: junk at end of line...

分析:汇编器无法识别新版 Clang 生成的调试信息格式(DWARF 版本不兼容)。

解决(二选一):

  • 降低 Clang 版本(例如从 Clang 20 降至 Clang 12)
  • MakefileKBUILD_CFLAGS 中添加以下标志,强制使用兼容格式:
KBUILD_CFLAGS += -gdwarf-4

代码语法与逻辑错误

Q9:提示 undefined reference to ...

分析:链接错误。函数已声明但找不到具体实现(缺少库或目标文件)。

解决

  • 检查是否缺少链接库(如 -lssl
  • 确认库路径已正确写入 LDFLAGS
  • 检查函数名是否存在拼写错误

Q10:提示 misleading-indentation 警告或错误?

分析:代码缩进与逻辑控制块(if / for / while)不匹配,存在潜在逻辑陷阱。

解决:为相关语句添加大括号 {} 明确代码范围。


Q11:提示 type specifier missingmakes pointer from integer...

分析:C 语言类型声明缺失,或类型不匹配(如将整数当指针使用)。

解决

  • 检查变量声明是否缺少 int 等类型关键字
  • 确认所使用的内核 API 是否随版本发生了变化

其他构建问题

Q12:提示 multiple definition of 'yylloc'

分析:这是内核旧版本代码与新版 GCC 之间的一个已知冲突问题。

解决:修改 scripts/dtc/dtc-lexer.lex.c_shipped,将以下行:

YYLTYPE yylloc;

改为:

extern YYLTYPE yylloc;

Q13:看到 make[N]: *** [Error X] 形式的错误?

分析:这是 Makefile 构建失败的通用标志,本身不包含有效信息。

解决:这一行只是结果,真正的错误原因在它之上。向上翻阅日志,找到 gccldsh 返回的具体报错信息。