通过make编译多文件的内核模块
来源:互联网 发布:揭秘网络赚钱的门道 编辑:程序博客网 时间:2024/05/20 10:10
转载至:http://edsionte.com/techblog/archives/4059
之前对make的使用都仅局限于单个文件,比如用make编译单个文件的内核模块。我试着将一个程序分解成多个文件,然后再通过make进行多文件的编译,途中还是遇到一些列问题,因此总结成下文。
1.文件清单
下面的文件清单类出的是一个内核模块程序,我们这里不去深究这个模块的功能。procfs_mod.c主要包含内核模块程序的主要框架,比如加载函数和卸载函数等;procfs.c包含主要的函数的实现;而procfs.h是整个程序所用到的头文件,包含函数以及变量的声明等。
1
edsionte@edsionte-desktop:~/proc_vfs$ ls
2
Makefile procfs.c procfs.h procfs_mod.c
2.Makefile的组成
我们可以将Makefile看作是编译规则集合,它告诉make应该如何进行编译,最终生成目标文件。
1
edsionte@edsionte-desktop:~/proc_vfs$ cat Makefile
2
obj-m += myprocfs.o
3
myprocfs-objs := procfs.o procfs_mod.o
4
5
all:
6
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
7
clean:
8
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean
在这个Makefile中,obj-m说明最终生成的内核模块目标文件是myprofs.ko,并且它必须依赖两个文件procfs.c和procfs_mod.c。因此,通过模块名加-objs的形式可以定义整个模块所包含的文件。注意,这里定义的都是与原文件同名的目标文件。
3.头文件的引用
在本文所举例的源程序中,procfs.h包含了整个程序所需要的函数以及变量,也即是说所有.c的源程序都会引用该头文件。为了防止头文件被多次重复引用,我们应该在头文件中使用条件编译。
1
edsionte@edsionte-desktop:~/proc_vfs$ cat procfs.h
2
#ifndef _MY_PROC_FS_H
3
#define _MY_PROC_FS_H
4
5
#include
6
…………
7
#endif
也就是将整个头文件的内容用头文件包围起来。上面的条件编译说明:如果没有定义符号常量_MY_PROC_FS_H,就定义该变量并且包含该头文件。
但是,即便我在头文件中使用了条件编译,在编译时还是出现了下面的错误:
1
edsionte@edsionte-desktop:~/proc_vfs$ make
2
make -C /lib/modules/2.6.32-24-generic/build M=/home/edsionte/proc_vfs modules
3
make[1]: 正在进入目录 `/usr/src/linux-headers-2.6.32-24-generic'
4
CC [M] /home/edsionte/proc_vfs/procfs.o
5
CC [M] /home/edsionte/proc_vfs/procfs_mod.o
6
LD [M] /home/edsionte/proc_vfs/myprocfs.o
7
/home/edsionte/proc_vfs/procfs_mod.o:(.bss+0x820): multiple definition of `my_proc_file'
8
/home/edsionte/proc_vfs/procfs.o:(.bss+0x820): first defined here
9
/home/edsionte/proc_vfs/procfs_mod.o:(.data+0x80): multiple definition of `my_inode_ops'
10
/home/edsionte/proc_vfs/procfs.o:(.data+0x80): first defined here
11
make[2]: *** [/home/edsionte/proc_vfs/myprocfs.o] 错误 1
12
make[1]: *** [_module_/home/edsionte/proc_vfs] 错误 2
13
make[1]:正在离开目录 `/usr/src/linux-headers-2.6.32-24-generic'
14
make: *** [all] 错误 2
产生这种错误的原因是我之前一直在头文件对一些全局变量进行定义,这样导致进行了多次定义。正确的做法是在某一个.c中进行全局变量的定义,而在.h文件中使用extern进行外部即可。
- 通过make编译多文件的内核模块
- 编译多个文件到内核模块
- 内核模块的编译
- 内核编译make oldconfig的作用
- make ***config 编译内核的主要区别
- LINUX 2.6 内核下多C文件模块编译方法
- 编译内核模块的方法
- 编译内核模块的makefile
- 编译内核模块的makefile
- 编译内核模块的Makefile
- 编译内核模块的Makefile
- linux内核模块的编译
- 内核编译(make)
- 内核编译(make)
- Linux内核模块:模块的编译
- 正确地保存编译内核产生的.config文件-使用make savedefconfig
- debian内核编译make menuconfig提示缺少库文件
- Android Goldfish内核编译 + eCryptfs文件加解密系统的内核模块配置
- [LeetCode]Find Minimum in Rotated Sorted Array I&II
- 树莓派连接天然气模块
- C++异常以及错误处理
- Groovy在ADF BC中的常见用法之一
- SWT中的进度条
- 通过make编译多文件的内核模块
- Mybatis Mapper动态代理方法 即 只写Dao接口 不谢Dao的实现类
- iOS 8 Xcode6 设置Launch Image 启动图片<转>
- HDU 1248(寒冰王座)基础完全背包
- iOS开发UI篇—CALayer简介
- 深入研究Servlet线程安全性问题
- Http请求之HttpClient + AsyncTask异步请求
- C++运算符重载
- HDOJ 题目2896 病毒侵袭(AC自动机)