微知-Mellanox OFED编译的一些细节?无法编译怎么办?如何添加自定义编译选项?
0. 背景
本文记录Mellanox OFED编译的一些常见问题,经常有人问或者遇到,特此记录。Mellanox OFED编译框架,从文件视角是configure脚本进行配置检查和配置,makefile进行编译管理,结合内核编译框架完成最终编译,configure之后基本遵循内核这一套。
1. 要点
- configure本质是一个shell脚本,接受–xxx的shell参数,会先定义shell变量,然后根据shell变量,定义makefile变量到configure.mk.kernel或其他中
- Makefile脚本中定义了根据configre指定的CONFIG的Makefile变量,决定编译哪些模块,makefile中定义了编译规则,比如make install的tag
- compat/config.h configure之后自动生成的动态头文件,如果未config会编译报错,配置文件放在这里
- config的日志在compat/config.log中,如果config失败,可以从这里查看
- 如果要查看详细编译过程 使用 make -j V=1 #V=1表示verbose模式,可以查看详细gcc参数
- 还有一个查看gcc参数的方法:每个目录下面对应的文件,有隐藏文件.xxxfile.o.cmd 该部分会存储详细编译参数,可以在自定义编译的时候查看参数是否符合预期等
关键要点
./configure 之后的CONFIG参数会放到当前目录的configure.mk.kernel中
./configure xxx之后,会有很多配置,比如–with-mlxfw,该配置参数本质会定义一个CONFIG_MLXFW的
如何添加一个自定义的configure参数,并且能够生效到Makefile以及C语言中
以添加一个configure编译时候的参数–with-my-mode参数为例:
最终需要定义一个./configure xxxx --with-my-mode的参数,支持编译一个新增的目录
- 在configure中修改:在configure的参数help中设置,可以放到–with-mlxfw-mod后面
--with-my-mod make CONFIG_MY_MOD=m [no]
- 在configure中修改:switch case中根据shell参数,定义shell变量
--with-my-mod)CONFIG_MY_MOD="m" #这里定义为m,是因为makefile中有obj-$(CONFIG_MY_MOD)来决定怎么编译这个;;#假设要支持一个指定自定义值的方式 比如./configure --with-my-version V1.1.1,需要在case中用shift偏移变量,比如--with-my-version)shiftCONFIG_MY_VERSION=$1 #只是这里定义的值是自定义字符串,和前面的定义的值是m用来告知内核态ko编译模式为module稍微差别
- 在makefile中修改:CONFIG_MLXFW后添加编译变量
CONFIG_MY_MOD=$(CONFIG_MY_MOD) \
- 在OFED顶层Makefile中定义编译子目录
obj-$(CONFIG_MY_MOD) += driver/mymode #所以这种需要在前面解析configure的shell脚本结果指定为m
- 在自定义子目录Makefile中接收内核编译框架传过来的新模块变量configure.mk.kernel中
MY_MOD_TOPDIR=$(PWD)/path/to/mymodule
subdir-ccflags-y += -I$(MY_MOD_TOPDIR)/ \-DCONFIG_MY_VERSION='-$(CONFIG_MY_VERSION)-' #这里添加-前后缀避免是空值
这里是将makefile的变量以及传递给gcc里面的变量都是用相同的名字。当然这里也可以不用相同的名字
- 在自定义的c语言中使用./configure传递过来的带变量的值CONFIG_MY_VERSION
//c语言中直接当做一个宏定义使用
if (strlen(CONFIG_MY_VERSION) > 0) {printk("version: %s\n"), CONFIG_MY_VERSION);
}
一些问题
./configure之后成功,编译的时候提示没有makefile
该问题可能是由于代码编译在mac系统存在不识别大小写makefile,造成覆盖,在ofed_scripts目录下,有Makefile和makefile两个文件,如果在mac系统上会出现。或者代码解压到mac,然后push到服务器。或者使用sftp等远程工具将代码放到远端。
./configure一直失败
- 可能是由于前面提到的makefile覆盖。
- 可能是有些参数指定方式不对,比如–with-xxx abc,写成–with-xxx=abc
修改源码或者makefile之后重新编译未生效
修改文件编译系统未感知
一般修改c源码会自动生效修改.h和Makefile或者mk文件可能不生效,建议每次编译都 find . -name "*.c" | xargs -I {} touch {};
还可能是由于修改了错误路径的代码
该问题,可以每次用#error 等方式明确修改。
关于修改错误路径或者位置代码,可能有些原因:
- 做了backup代码,名字相同,早错修改错误
- copy代码后,并未修改原来代码中的内容,造成打印相同
- copy makefile后,所使用的目标obj并未变化,造成未编译进去
- sftp等工具,并未正确的同步,或者同步失败了
- sftp等工具本端修改代码,并且删掉临时文件,远端还在,同时未同步修改makefile继续编译了远端的文件
还可能是由于
综述
不断迭代关于Mellanox OFED相关问题