You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux内核编译时如何排除drivers/pci目录编译但保留符号引用?

问题描述

把项目编译器从gcc 9.3换成clang 11后,drivers/pci目录里的部分文件没法用新编译器编译。临时方案是用gcc编译好这些文件后复制过来,但执行make时这个目录还是会被重新编译,导致错误反复出现。

已尝试的解决方案

  • 修改文件时间戳:把pci目录下所有gcc编译的文件时间戳改成2000年左右,试图影响Makefile的构建逻辑,但重新构建时该目录依然会被编译。
  • 注释Makefile中的目录:把drivers目录下Makefile里的objm+= /pci行注释掉,结果内核里其他需要引用pci目录.o文件符号的文件在链接时报错:
    ld.lld: error: undefined symbol: pci_find_bus
    >>> referenced by pci.c:40 (kernel/arch/arm64/kernel/pci.c:40)
    
解决方案

方法1:将预编译的.o文件打包成静态库,修改Makefile链接该库

  1. 把pci目录下已编译好的.o文件打包成静态库:
    ar rcs drivers/pci/libpci.a drivers/pci/*.o
    
  2. 注释掉drivers目录Makefile里的objm+= /pci行,避免触发pci目录的编译流程。
  3. 在顶层Makefile或者drivers的Makefile中添加链接静态库的配置:
    # 内核构建场景下,用EXTRA_LDFLAGS指定库路径和库名
    EXTRA_LDFLAGS += -Ldrivers/pci -lpci
    # 或者直接把静态库加入链接目标列表
    obj-y += drivers/pci/libpci.a
    

方法2:修改pci目录的Makefile,跳过源文件编译

直接替换drivers/pci目录下的Makefile内容,去掉所有编译.c文件的规则,只声明已有的.o文件为目标:

# 列出所有已经用gcc编译好的.o文件名
obj-y := pci_dev.o pci_bus.o xxx.o
# 移除所有%.o: %.c之类的编译规则,让make不会尝试重新编译源文件

补充:为什么修改时间戳没用?

Makefile的依赖检查逻辑通常是对比源文件(.c)和目标文件(.o)的时间戳,只要.c文件的时间戳比.o新,就会触发重新编译。即使你修改了.o的时间戳,源文件本身的时间戳还是更新的,所以依然会触发编译流程。

内容的提问来源于stack exchange,提问作者alex zhang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 17:42:35