首页 > *nix技术, 内核技术, 跟踪调试 > 利用error指令判断宏是否已定义

利用error指令判断宏是否已定义

2012年2月24日 发表评论 阅读评论 8,875 次浏览

Linux下特别的东西特别的多,比如说宏定义,看Linux内核代码,无数个宏开关,当然,这并不是Linux的过错,要知道Linux内核特性的开启与否都要靠这些宏定义。
在判断一个宏定义是否开启时,各人有各人的办法,最简单的当然是直接看代码,但这不一定准确,因为有可能此处define的宏在别处又undef了,在代码实际用到这个宏的地方,这个宏到底是否还存在呢?所以,最保险的方法就是在实际用到这个宏的地方做判断,此时可利用error指令,在编译时就可以准确判断出结果,直接看示例:

# Makefile
 
MDIR = $(shell pwd)
 
ifeq (, $(KSRC))
	KSRC := /usr/src/linux-`uname -r`
endif
 
ifeq (, $(PROJECT_DIR))
	PROJECT_DIR := $(PWD)/../
endif
 
module := test_macro
 
obj-m := $(module).o
 
srcs =  $(wildcard, *.c)
 
$(module)-objs := $(addsuffix .o, $(basename $(srcs)))
 
EXTRA_CFLAGS += -g $(FLAG) -I$(PROJECT_DIR)/inc -I${SHAREDHDR} -I$(KERNELHDR) -O2 -D__KERNEL__ -DMODULE $(INCLUDE) -DEXPORT_SYMTAB 
 
TARGET = $(module).ko
 
all:
	make -C $(KSRC) M=$(MDIR) modules
 
debug:
	make EXTRA_FLAGS="${EXTRA_CFLAGS} -DDEBUG" -C $(KSRC) M=$(MDIR) modules
 
clean:
	make -C $(KSRC) M=$(MDIR) clean
 
install: all
	cp -f $(TARGET) $(INSTALL_DIR)

/**
 * test_macro.c
 */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/module.h>
#include <linux/fs.h>

#define HAVE_TX_MQ

static int __init test_macro_init(void)
{
#ifndef HAVE_TX_MQ

   #error HAVE_TX_MQ not define 

#endif

    return 0;
}
 
static void __exit test_macro_fini(void)
{
 
    //Do Nothing
    return;
}
 
module_init(test_macro_init);
module_exit(test_macro_fini);
 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("lenky0401 at gmail dot com");

由于在源文件test_macro.c的前面定义了HAVE_TX_MQ宏,所以编译正常:

[root@localhost k]# make
make -C /usr/src/linux-`uname -r` M=/home/lenky/k modules
make[1]: Entering directory `/usr/src/linux-2.6.38.8'
  CC [M]  /home/lenky/k/test_macro.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/lenky/k/test_macro.mod.o
  LD [M]  /home/lenky/k/test_macro.ko
make[1]: Leaving directory `/usr/src/linux-2.6.38.8'
[root@localhost k]# 

假若把“#define HAVE_TX_MQ”换成“#undef HAVE_TX_MQ”,再编译则会报错:

[root@localhost k]# sed --in-place -e 's/#define/#undef/' test_macro.c 
[root@localhost k]# head -n 15 test_macro.c
/**
 * test_macro.c
 */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/module.h>
#include <linux/fs.h>

#undef HAVE_TX_MQ

static int __init test_macro_init(void)
{
#ifndef HAVE_TX_MQ

[root@localhost k]# make
make -C /usr/src/linux-`uname -r` M=/home/lenky/k modules
make[1]: Entering directory `/usr/src/linux-2.6.38.8'
  CC [M]  /home/lenky/k/test_macro.o
/home/lenky/k/test_macro.c:16:5: error: #error HAVE_TX_MQ not define
make[2]: *** [/home/lenky/k/test_macro.o] Error 1
make[1]: *** [_module_/home/lenky/k] Error 2
make[1]: Leaving directory `/usr/src/linux-2.6.38.8'
make: *** [all] Error 2
[root@localhost k]# 

这样,我们就能准备的判断某处使用的宏是否已经定义,方便我们在不实际执行代码的情况下知道程序流程走向,帮助理解源代码。

转载请保留地址:http://www.lenky.info/archives/2012/02/1184http://lenky.info/?p=1184


备注:如无特殊说明,文章内容均出自Lenky个人的真实理解而并非存心妄自揣测来故意愚人耳目。由于个人水平有限,虽力求内容正确无误,但仍然难免出错,请勿见怪,如果可以则请留言告之,并欢迎来讨论。另外值得说明的是,Lenky的部分文章以及部分内容参考借鉴了网络上各位网友的热心分享,特别是一些带有完全参考的文章,其后附带的链接内容也许更直接、更丰富,而我只是做了一下归纳&转述,在此也一并表示感谢。关于本站的所有技术文章,欢迎转载,但请遵从CC创作共享协议,而一些私人性质较强的心情随笔,建议不要转载。

法律:根据最新颁布的《信息网络传播权保护条例》,如果您认为本文章的任何内容侵犯了您的权利,请以Email或书面等方式告知,本站将及时删除相关内容或链接。

  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.