fatal error: stdarg.h: No such file or directory错误的一种冷门原因

背景

最近把编译环境从Ubuntu1604 64bit升级成了Ubuntu2004 64bit,然后以前能编译的Linux驱动模块(x86,不是x64)现在突然不能编译了,提示:

whp@whp-HP-ProDesk-400-G5-MT:~/projects/F267/SVN/driver_x86/pcie_network$ make ARCH=x86
make -C ~/linux-source-4.15.0 M=/home/whp/projects/F267/SVN/driver_x86/pcie_network
make[1]: 进入目录“/home/whp/linux-source-4.15.0”
  CC [M]  /home/whp/projects/F267/SVN/driver_x86/pcie_network/fpga_dsp.o
In file included from ./include/linux/list.h:9,
                 from ./include/linux/module.h:9,
                 from /home/whp/projects/F267/SVN/driver_x86/pcie_network/fpga_dsp.c:14:
./include/linux/kernel.h:6:10: fatal error: stdarg.h: 没有那个文件或目录
    6 | #include <stdarg.h>
      |          ^~~~~~~~~~
compilation terminated.

定位解决

Makefile如下:

KDIR=~/linux-source-4.15.0
PWD=$(shell pwd)
ARCH=x86

obj-m += fpga_dsp.o

EXTRA_CFLAGS += -Wno-error=date-time       # Fix compile error on gcc 4.9 and later   不做错误报出
EXTRA_CFLAGS +=-Wno-date-time              #不做警告报出

all:
    $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(PWD)
clean:
    @rm -fr *.o *.mod.c *.ko .*.cmd .tmp_versions *.out *.symvers *.order .cache.mk *.ur-safe

既然以前可以编译,且代码没做任何修改,那就是编译环境变化所致,对比Ubuntu1604的gcc跟Ubuntu2004的gcc,发现前者是v4(v5备选),后者是v9(v7备选),尝试将gcc版本从v9降低为v7(给make传递CC=gcc-7环境变量)

结果编译通过:

whp@whp-HP-ProDesk-400-G5-MT:~/projects/F267/SVN/driver_x86/pcie_network$ make ARCH=x86 CC=gcc-7
make -C ~/linux-source-4.15.0 M=/home/whp/projects/F267/SVN/driver_x86/pcie_network
make[1]: 进入目录“/home/whp/linux-source-4.15.0”
  CC [M]  /home/whp/projects/F267/SVN/driver_x86/pcie_network/fpga_dsp.o
symbolmap: 00000000: invalid section
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/whp/projects/F267/SVN/driver_x86/pcie_network/fpga_dsp.mod.o
  LD [M]  /home/whp/projects/F267/SVN/driver_x86/pcie_network/fpga_dsp.ko
make[1]: 离开目录“/home/whp/linux-source-4.15.0”

分析

我搜了下stdarg.h,发现它貌似只出现在交叉工具链里,host工具链是不包含该文件的。

让工程同时支持2004和1604

给原来的Makefile的ARCH=x86一行后面添加如下片段:

UBUNTU_VER_RAW=$(shell lsb_release -a 2>/dev/null | grep Release | cut -d ':' -f 2)
UBUNTU_VER=$(strip $(UBUNTU_VER_RAW))
ifeq ($(UBUNTU_VER), 20.04)
CC=gcc-7
else ifeq ($(UBUNTU_VER), 16.04)
CC=gcc-5
else
CC=$(UBUNTU_VER)
endif

同时将CC=$(CC)添加到$(make)行里,免得再去凭记忆敲命令行:

all:
    $(MAKE) ARCH=$(ARCH) CC=$(CC) -C $(KDIR) M=$(PWD)

总结

并不是在x86上编译arm才算交叉编译,x64 gcc编译给x86 gcc写的代码也算交叉编译。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值