linux c 宏 linux用什么软件写程序

大家好,今天小编来为大家解答linux c 宏这个问题,linux用什么软件写程序很多人还不知道,现在让我们一起来看看吧!

Linux内核根目录中的配置文件.config中包含了许多宏定义,

一、Linux内核的配置系统由三个部分组成,分别是:

1、Makefile:分布在 Linux内核源代码根目录及各层目录中,定义 Linux内核的编译规则;

2、配置文件(config.in(2.4内核,2.6内核)):给用户提供配置选择的功能;

3、配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置用户界面(提供基于字符界面、基于 Ncurses图形界面以及基于 Xwindows图形界面的用户配置界面,各自对应于 Make config、Make menuconfig和 make xconfig)。这些配置工具都是使用脚本语言,如 Tcl/TK、Perl编写的(也包含一些用 C编写的代码)。本文并不是对配置系统本身进行分析,而是介绍如何使用配置系统。所以,除非是配置系统的维护者,一般的内核开发者无须了解它们的原理,只需要知道如何编写 Makefile和配置文件就可以。

二、Make menuconfig过程分析

1、scripts文件夹存放的是跟make menuconfig配置界面的图形绘制相关的文件,我们作为使用者无需关心这个文件夹的内容

2、读取arch/arch/$ARCH/Kconfig以及各子目录下的Kcondig文件,生成配置条目。

$ARCH由linux内核根目录下的makefile文件决定

ARCH?= arm

CROSS_COMPILE?= arm-linux-

Kconfig文件中为配置信息的宏定义,与我们在make menuconfig图形界面看到的信息一致。

例如:

config CPU_S3C2410_DMA

bool

depends on S3C2410_DMA&&(CPU_S3C2410|| CPU_S3C2442)

default y if CPU_S3C2410|| CPU_S3C2442

help

DMA device selection for S3C2410 and compatible CPUs

因此,Kconfig文件很重要的作用就是:定义配置宏、相关依赖关系、帮助信息

3、读取内核根目录下.config文件,生成配置选项:[*]编译进内核 [M]编译为模块 [ ]不编译

arch/arm/configs/文件夹下存放了一些配置模板

我们可以通过cp/arch/arm/configs/xx_defconfig.config来使用这些配置模板

通过图形界面变更配置选项会自动更新到.config文件中

make disclean会删除.config

4、编译过程根据.config生成 Linux内核根目录下的 include/config/auto.conf文件

CONFIG_EEPROM_93CX6=m

CONFIG_DM9000=y

根目录Makefile以及子目录的Makefile根据auto.conf生成编译条件

obj-$(CONFIG_DM9000)+= dm9000.o//obj-m+= dm9000.o

5、编译过程根据.config生成Linux内核根目录下的 include/linux/autoconf.h文件

.config或 auto.conf中定义要编译为 m模块的项,如:

CONFIG_DEBUG_NX_TEST=m

在 autoconf.h中会被定义为:

#define CONFIG_DEBUG_NX_TEST_MODULE 1

.config或auto.conf中定义为编译为 y的选项,如:

CONFIG_DM9000= y

在 autoconf.h中会被定义为:

#define CONFIG_DM9000 1

autoconf.h中是.config或者auto.conf中配置信息的另一种体现形式,它是站在源码的角度,供源码使用的C语言宏定义。

6、总结

我们在使用make menuconfig时,首先会确定架构arch,然后读取arch目录的Kconfig中的配置宏定义,生成编译条目,然后读取Linux内核根目录下的.config选项,将.config中的配置信息显示在图形界面上[*] [M] or []。我们在图形界面中更改配置选项会自动保存到.config文件中。编译过程根据.config随后生成auto.conf文件,它决定了makefile中各个文件的编译类型,静态编译进内核、编译成模块、不编译;同时生成autoconf.h,它以C语言宏定义的形式表达了各个文件是否被编译,源码中会判断某文件是否被编译进行不同的处理。

三、将自定义文件添加进内核配置系统

1、修改文件目录下Kconfig文件

添加:

config HELLO

tristate"just a test hello"

default y

---help---

This is a test

//tristate或 bool表示可选择种类数量3[*][M][ ]、2

//"just a test hello"将作为标题显示在配置的图形界面

2、修改文件目录下makefile文件

obj-$(CONFIG_HELLO)+= hello_drv.o

3、make menuconfig我们会在字符设备驱动的界面看到 ust a test hello并且默认编译进内核

4、make编译内核发现

autoconfig.h自动添加#define CONFIG_HELLO 1

auto.conf自动添加 CONFIG_HELLO=y

Linux内核中的C语言宏:常见用法和最佳实践

深入探索Linux内核中的C语言宏艺术:定义、对比与实践

在Linux内核开发中,C语言宏是一种强大的工具,它们作为预处理指令,通过文本替换提升代码复用和可维护性。让我们一起探索它们的常见用法和最佳实践。

宏与函数的差异

宏在预编译阶段展开,无需函数调用的开销,不返回值,编译时进行错误检查。相反,函数在运行时执行,有返回值,编译器会对其进行优化。尽管如此,宏的优势在于提高效率和简化代码,但可能带来代码膨胀和问题的风险,如类型不安全。

宏的优缺点

优点:提高代码执行速度,减少冗余,灵活应对复杂情况

缺点:可能导致代码难以理解和维护,易引发错误,如宏展开的副作用

Linux内核中,#define常用于定义常量,如整数、字符串和枚举,如常量MAX_NUM和MY_CHAR的定义。

const关键字与宏的比较

尽管C语言提供const关键字定义不可变常量,它具有类型安全、可读性强和维护性好的优点。相比之下,const常量在编译时检查类型,无生存期副作用,且有符号表入口,更加安全。

函数式宏的示例与使用

函数样式宏如ADD(x, y)=(x)+(y),虽然提供速度和灵活性,但调试困难,可读性较差。在内核开发中,需谨慎使用,如在处理最大值/最小值、数组长度、断言和字符串连接等场景。

条件编译的妙用

#ifdef与#ifndef控制基于宏定义的编译块

#if与#elif根据表达式选择代码段,注意控制复杂性

这些条件编译指令允许代码根据平台或配置适应性编译,但过多使用可能影响代码清晰度。

内联函数与宏的对比

内联函数如add(int a, int b),通过编译时展开提高效率,但要留意函数体大小和结构对性能的影响。使用时应权衡效率与可读性。

最佳实践与注意事项

遵循命名规范,清晰标识宏

详尽的注释,解释宏的作用和参数

适度使用,避免过度宏膨胀和可读性降低

为调试目的,可使用#define定义调试宏

总之,理解并明智地运用C语言宏在Linux内核开发中至关重要,既能提升代码效率,又能维护良好的代码结构。在实际操作中,要注重可读性、可维护性和性能优化的平衡。

c语言中的“宏”是指什么

宏是一种预处理指令,它提供了一种机制,可以用来替换源代码中的字符串。

1、条件编译:

C语言中,预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行相应的转换,预处理过程还会删除程序中的注释和多余的空白符号。

预处理指令是以#开头的代码行,#必须是该行除了空白字符外的第一个字符。#后是指令关键字,在#和指令关键字之间允许存在若干空白字符。

使用宏进行条件编译的用法与使用宏防止多重引用类似。示例如下:

使用条件编译,方便程序员在调试程序的过程中,执行一些在程序发布后并不需要执行的指令。只要在需要调试的代码前加上_DEBUG的定义,就可以在调试程序的过程中输出调试信息。

这样方便查看程序在运行过程中有没有出现错误,定位错误出现的地方。而在程序发布之前,取消_DEBUG的定义就可以不再执行调试代码。

2、宏函数:

函数的调用是需要一定的时间和空间代价的。因为系统在调用函数时,需要保留"现场",即将程序要执行的指令的下一条指令的位置压入栈,然后转入调用函数去执行,调用完函数后再返回主调函数,恢复"现场",返回到栈里保存的的下一条指令的位置继续执行。

所以函数的调用需要额外的时间和空间代价。

而宏函数则不存在上述问题,宏函数在预编译时,同函数定义的代码来替换函数名,将函数代码段嵌入到当前程序,不会产生函数调用。

所以会省去普通函数保留现场恢复现场的时间,但因为要将定义的函数体嵌入到当前程序,所以不可避免的会占用额外的存储空间。

在频繁调用同一个宏的时候,该现象尤其明显。宏函数的示例定义如下:

#define MAX(a,b)((a)<(b)?(b):(a))

宏函数的优点在于避免函数调用,提高程序效率。

同时需要注意的是inline标识符。inline也将函数定义为内联的。但是使用内联函数需要注意的是:函数体必须十分简单,不能含有循环、条件、选择等复杂结构,否则就不能作为内联函数了。

事实上,有时候即便你没有将函数指定为内联函数,编译器也会将一些简单的函数作为内联函数处理,而对于一些复杂的函数,即使声明为内联函数,编译器也不会理会的。

inline函数的瓶颈就在于此,使用inline标识符将函数声明为内联的,但这只是一种提示,到底编译器有没有优化还依赖于编译器的实现,而使用宏函数则完全由代码本身控制。

但在使用宏函数的时候,需要明确的是宏函数只是简单的替换,需要注意括号的使用。

扩展资料:

宏的更多规则特性:

(1)宏名一般用大写。

(2)使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。例如:数组大小常用宏定义。

(3)预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查。

(4)宏定义末尾不加分号。

(5)宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头。

(6)可以用#undef命令终止宏定义的作用域。

(7)宏定义不可以嵌套。

(8)字符串""中永远不包含宏。

(9)宏定义不分配内存,变量定义分配内存。

(10)宏定义不存在类型问题,它的参数也是无类型的。

参考资料:

百度百科--宏定义

阅读剩余
THE END