×

linuxmakefile编写

linuxmakefile编写(Linux平台Makefile文件的编写基础篇)

admin admin 发表于2024-04-21 04:54:58 浏览20 评论0

抢沙发发表评论

本篇文章给大家谈谈linuxmakefile编写,以及Linux平台Makefile文件的编写基础篇对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。

本文目录

Linux平台Makefile文件的编写基础篇

目的: 基本掌握了 make 的用法,能在Linux系统上编程。 环境: Linux系统,或者有一台Linux服务器,通过终端连接。一句话:有Linux编译环境。 准备: 准备三个文件:file1.c, file2.c, file2.h file1.c: #include #include "file2.h" int main() { printf("print file1$$$$$$$$$$$$ "); File2Print(); return 0; }

file2.h:

#ifndef FILE2_H_ #define FILE2_H_

#ifdef __cplusplus

extern "C" {

#endif

void File2Print();

#ifdef __cplusplus

}

#endif

#endif

file2.c: #include "file2.h" void File2Print() { printf("Print file2********************** "); }

基础: 先来个例子: 有这么个Makefile文件。(文件和Makefile在同一目录) === makefile 开始 === helloworld:file1.o file2.o gcc file1.o file2.o -o helloworld file1.o:file1.c file2.h gcc -c file1.c -o file1.o

file2.o:file2.c file2.h

gcc -c file2.c -o file2.o

clean:

rm -rf *.o helloworld

=== makefile 结束 ===

一个 makefile 主要含有一系列的规则,如下: A: B (tab) (tab)

每个命令行前都必须有tab符号。

上面的makefile文件目的就是要编译一个helloworld的可执行文件。让我们一句一句来解释:

helloworld : file1.o file2.o: helloworld依赖file1.o file2.o两个目标文件。

gcc File1.o File2.o -o helloworld: 编译出helloworld可执行文件。-o表示你指定 的目标文件名。

file1.o : file1.c: file1.o依赖file1.c文件。

gcc -c file1.c -o file1.o: 编译出file1.o文件。-c表示gcc 只把给它的文件编译成目标文件, 用源码文件的文件名命名但把其后缀由“.c”或“.cc”变成“.o”。在这句中,可以省略-o file1.o,编译器默认生成file1.o文件,这就是-c的作用。

file2.o : file2.c file2.h gcc -c file2.c -o file2.o

这两句和上两句相同。

clean:

rm -rf *.o helloworld

当用户键入make clean命令时,会删除*.o 和helloworld文件。

如果要编译cpp文件,只要把gcc改成g++就行了。

写好Makefile文件,在命令行中直接键入make命令,就会执行Makefile中的内容了。

到这步我想你能编一个Helloworld程序了。

上一层楼:使用变量

上面提到一句,如果要编译cpp文件,只要把gcc改成g++就行了。但如果Makefile中有很多gcc,那不就很麻烦了。

第二个例子:

=== makefile 开始 === OBJS = file1.o file2.o CC = gcc CFLAGS = -Wall -O -g helloworld : $(OBJS) $(CC) $(OBJS) -o helloworld file1.o : file1.c file2.h $(CC) $(CFLAGS) -c file1.c -o file1.o file2.o : file2.c file2.h $(CC) $(CFLAGS) -c file2.c -o file2.o

clean:

rm -rf *.o helloworld === makefile 结束 ===

这里我们应用到了变量。要设定一个变量,你只要在一行的开始写下这个变量的名字,后 面跟一个 = 号,后面跟你要设定的这个变量的值。以后你要引用 这个变量,写一个 $ 符号,后面是围在括号里的变量名。

CFLAGS = -Wall -O –g,解释一下。这是配置编译器设置,并把它赋值给CFFLAGS变量。

-Wall: 输出所有的警告信息。

-O: 在编译时进行优化。

-g: 表示编译debug版本。

这样写的Makefile文件比较简单,但很容易就会发现缺点,那就是要列出所有的c文件。如果你添加一个c文件,那就需要修改Makefile文件,这在项目开发中还是比较麻烦的。

再上一层楼:使用函数

学到这里,你也许会说,这就好像编程序吗?有变量,也有函数。其实这就是编程序,只不过用的语言不同而已。

第三个例子:

=== makefile 开始 === CC = gcc

XX = g++ CFLAGS = -Wall -O –g

TARGET = ./helloworld

%.o: %.c

$(CC) $(CFLAGS) -c lt; -o

%.o:%.cpp

$(XX) $(CFLAGS) -c lt; -o

SOURCES = $(wildcard *.c *.cpp) OBJS = $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES)))

$(TARGET) : $(OBJS) $(XX) $(OBJS) -o $(TARGET)

chmod a+x $(TARGET)

clean:

rm -rf *.o helloworld === makefile 结束 ===

函数1:wildcard

产生一个所有以 ’.c’ 结尾的文件的列表。

SOURCES = $(wildcard *.c *.cpp)表示产生一个所有以 .c,.cpp结尾的文件的列表,然后存入变量 SOURCES 里。

函数2:patsubst

匹配替换,有三个参数。第一个是一个需要匹配的式样,第二个表示用什么来替换它,第三个是一个需要被处理的由空格分隔的列表。

OBJS = $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCES)))表示把文件列表中所有的.c,.cpp字符变成.o,形成一个新的文件列表,然后存入OBJS变量中。

%.o: %.c

$(CC) $(CFLAGS) -c lt; -o

%.o:%.cpp

$(XX) $(CFLAGS) -c lt; -o

这几句命令表示把所有的.c,.cpp编译成.o文件。

这里有三个比较有用的内部变量。 扩展成当前规则的目的文件名, lt; 扩展成依靠 列表中的第一个依靠文件,而 $^ 扩展成整个依靠的列表(除掉了里面所有重 复的文件名)。

chmod a+x $(TARGET)表示把helloworld强制变成可执行文件。

linux上的makefile怎么使用

一、Makefile的规则在讲述这个Makefile之前,还是先来粗略地看一看Makefile的规则。target ... : prerequisites ...command.......target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。prerequisites就是,要生成那个target所需要的文件或是目标。command也就是make需要执行的命令。(任意的Shell命令)这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。二、一个示例正如前面所说的,如果一个工程有3个头文件,和8个C文件,为了完成前面所述的那三个规则,的Makefile应该是下面的这个样子的。edit : main.o kbd.o command.o display.o \insert.o search.o files.o utils.occ -o edit main.o kbd.o command.o display.o \insert.o search.o files.o utils.omain.o : main.c defs.hcc -c main.ckbd.o : kbd.c defs.h command.hcc -c kbd.ccommand.o : command.c defs.h command.hcc -c command.cdisplay.o : display.c defs.h buffer.hcc -c display.cinsert.o : insert.c defs.h buffer.hcc -c insert.csearch.o : search.c defs.h buffer.hcc -c search.cfiles.o : files.c defs.h buffer.h command.hcc -c files.cutils.o : utils.c defs.hcc -c utils.cclean :rm edit main.o kbd.o command.o display.o \insert.o search.o files.o utils.o反斜杠(\)是换行符的意思。这样比较便于Makefile的易读。可以把这个内容保存在文件为“Makefile”或“makefile”的文件中,然后在该目录下直接输入命令“make”就可以生成执行文件edit。如果要删除执行文件和所有的中间目标文件,那么,只要简单地执行一下“make clean”就可以了。在这个makefile中,目标文件(target)包含:执行文件edit和中间目标文件(*.o),依赖文件(prerequisites)就是冒号后面的那些 .c 文件和 .h文件。每一个 .o 文件都有一组依赖文件,而这些 .o 文件又是执行文件 edit 的依赖文件。依赖关系的实质上就是说明了目标文件是由哪些文件生成的,换言之,目标文件是哪些文件更新的。在定义好依赖关系后,后续的那一行定义了如何生成目标文件的操作系统命令,一定要以一个Tab键作为开头。记住,make并不管命令是怎么工作的,他只管执行所定义的命令。make会比较targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新,或者target不存在的话,那么,make就会执行后续定义的命令。这里要说明一点的是,clean不是一个文件,它只不过是一个动作名字,有点像C语言中的lable一样,其冒号后什么也没有,那么,make就不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令。要执行其后的命令,就要在make命令后明显得指出这个lable的名字。这样的方法非常有用,可以在一个makefile中定义不用的编译或是和编译无关的命令,比如程序的打包,程序的备份,等等。三、makefile中使用变量在上面的例子中,先让看看edit的规则:edit : main.o kbd.o command.o display.o \insert.o search.o files.o utils.occ -o edit main.o kbd.o command.o display.o \insert.o search.o files.o utils.o可以看到文件,那么需要在两个地方加(应该是三个地方,还有一个地方在 clean中)。当然,的makefile并不复杂,所以在两个地方加也不累,但如果makefile变得复杂,那么我们就有可能会忘掉一个需要加入的地方,而导致编译失败。所以,为了makefile的易维护,在makefile中可以使用变量。makefile的变量也就是一个字符串,理解成 C语言中的宏可能会更好。比如,声明一个变量,叫objects, OBJECTS, objs, OBJS, obj, 或是 OBJ,反正不管什么啦,只要能够表示obj文件就行了。在makefile一开始就这样定义:objects = main.o kbd.o command.o display.o \insert.o search.o files.o utils.o于是,就可以很方便地在的makefile中以“$(objects)”的方式来使用这个变量了,于是的改良版makefile就变成下面这个样子:objects = main.o kbd.o command.o display.o \insert.o search.o files.o utils.oedit : $(objects)cc -o edit $(objects)main.o : main.c defs.hcc -c main.ckbd.o : kbd.c defs.h command.hcc -c kbd.ccommand.o : command.c defs.h command.hcc -c command.cdisplay.o : display.c defs.h buffer.hcc -c display.cinsert.o : insert.c defs.h buffer.hcc -c insert.csearch.o : search.c defs.h buffer.hcc -c search.cfiles.o : files.c defs.h buffer.h command.hcc -c files.cutils.o : utils.c defs.hcc -c utils.cclean :rm edit $(objects)于是如果有新的 .o 文件加入,只需简单地修改一下 objects 变量就可以了。四、make是如何工作的在默认的方式下,输入make命令通过makefile编译程序时,具体的内部机制如下:1、make会在当前目录下找名字叫“Makefile”或“makefile”的文件。2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。3、如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。4、如果edit所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)5、当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件生命make的终极任务,也就是执行文件edit了。这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。通过上述分析,知道,像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。于是在编程中,如果这个工程已被编译过了,当修改了其中一个源文件,比如file.c,那么根据的依赖性,的目标file.o会被重编译(也就是在这个依性关系后面所定义的命令),于是file.o的文件也是最新的啦,于是file.o的文件修改时间要比edit要新,所以edit也会被重新链接了(详见edit目标文件后定义的命令)。而如果改变了“command.h”,那么,kdb.o、command.o和files.o都会被重编译,并且,edit会被重链接。

linux 搭建stm32的makefile 怎么写

一 STM 32 GCC 安装 stm32 属于arm cortex-m系列thumb指令集,所以给arm用的arm-none-eabi就可以了,首先是下载 下载地址:***隐藏网址*** 下载其中的gcc-arm-none-eabi-version-linux.tar.bz2 解压到你知道的目录会产生 gcc-arm-none-eabi的文件夹 把该编译器添加到你的环境中: sudo gedit ~/.bashrc 在最后一行添加:export PATH=$PATH:/your_stm_gcc_dir/gcc-arm-none-eabi-4_8-2013q4/bin 因为我之前有添加过树莓派的编译器了,所以实际上是这样的:export PATH=$PATH:/your_pi_gcc_dir/tools-master/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/:/your_stm_gcc_dir/gcc-arm-none-eabi-4_8-2013q4/bin 两个编译器环境中间用冒号隔开; 注销后测试:arm-none-eabi-gcc -v 可以查看到该编译器的版本,就表示可以了.二 工程环境的建立 新建个工程文件夹,及其目录mkdir stm_projectcd stm_projectmkdir libsmkdir srcmkdir inc下载,安装官方库: stm32的寄存器不像51 avr等单片机,那么少,自己写写库,背背寄存器就可以了,所以ST公司提供了他们官方的库,为了避免重复造轮子,就直接采用他们的库,库版本为STM32_USB-FS-Device_Lib_V4.0.0,这个库多了usb支持,下载的话到st官网搜索stm32f10x就有了. 下载链接: stsw-stm32121.zip 解压,把解压好的文件夹复制到刚才新建的libs里面. 在工程根目录下新建Makefile.common文件,这个为通用makefile# include Makefile#This file is included in the general Makefile, the libs Makefile and the src Makefile#Different optimize settings for library and source files can be realized by using arguments#Compiler optimize settings:# -O0 no optimize, reduce compilation time and make debugging produce the expected results (default).# -O1 optimize, reduce code size and execution time, without much increase of compilation time.# -O2 optimize, reduce code execution time compared to ‘O1’, increase of compilation time.# -O3 optimize, turns on all optimizations, further increase of compilation time.# -Os optimize for size, enables all ‘-O2’ optimizations that do not typically increase code size and other code size optimizations.#Recommended optimize settings for release version: -O3#Recommended optimize settings for debug version: -O0#Valid parameters :# OptLIB=0 --》 optimize library files using the -O0 setting# OptLIB=1 --》 optimize library files using the -O1 setting# OptLIB=2 --》 optimize library files using the -O2 setting# OptLIB=3 --》 optimize library files using the -O3 setting# OptLIB=s --》 optimize library files using the -Os setting# OptSRC=0 --》 optimize source files using the -O0 setting# OptSRC=1 --》 optimize source files using the -O1 setting# OptSRC=2 --》 optimize source files using the -O2 setting# OptSRC=3 --》 optimize source files using the -O3 setting# OptSRC=s --》 optimize source files using the -Os setting# all --》 build all# libs --》 build libs only# src --》 build src only# clean --》 clean project# tshow --》 show optimize settings#Example:# make OptLIB=3 OptSRC=0 all tshowTOP=$(shell readlink -f "$(dir $(lastword $(MAKEFILE_LIST)))")PROGRAM=mainLIBDIR=$(TOP)/libs#Adust the following line to the library in use#=========add by embbnux 根据你的库不同,调整这个地方的库目录地址====================# STMLIB=$(LIBDIR)/STM32_USB-FS-Device_Lib_V4.0.0/Libraries#=========add by embbnux 根据你的stm32芯片型号容量不同,修改这个地方的TypeOfMCU=======##Adjust TypeOfMCU in use, see CMSIS file "stm32f10x.h"#STM32F103RBT (128KB FLASH, 20KB RAM) --》 STM32F10X_MD#TypeOfMCU=STM32F10X_MD#STM32F103RET (512KB FLASH, 64KB RAM) --》 STM32F10X_HD#STM32F103ZET (512KB FLASH, 64KB RAM) --》 STM32F10X_HD#============================================================================#TypeOfMCU=STM32F10X_HD#============================================================================#TC=arm-none-eabiCC=$(TC)-gccLD=$(TC)-ld -vOBJCOPY=$(TC)-objcopyAR=$(TC)-arGDB=$(TC)-gdbINCLUDE=-I$(TOP)/incINCLUDE+=-I$(STMLIB)/CMSIS/IncludeINCLUDE+=-I$(STMLIB)/CMSIS/Device/ST/STM32F10x/IncludeINCLUDE+=-I$(STMLIB)/CMSIS/Device/ST/STM32F10x/Source/TemplatesINCLUDE+=-I$(STMLIB)/STM32F10x_StdPeriph_Driver/incINCLUDE+=-I$(STMLIB)/STM32_USB-FS-Device_Driver/incCOMMONFLAGS=-g -mcpu=cortex-m3 -mthumbCOMMONFLAGSlib=$(COMMONFLAGS)#Commands for general Makefile and src Makefileifeq ($(OptSRC),0) COMMONFLAGS+=-O0 InfoTextSrc=src (no optimize, -O0)else ifeq ($(OptSRC),1) COMMONFLAGS+=-O1 InfoTextSrc=src (optimize time+ size+, -O1)else ifeq ($(OptSRC),2) COMMONFLAGS+=-O2 InfoTextSrc=src (optimize time++ size+, -O2)else ifeq ($(OptSRC),s) COMMONFLAGS+=-Os InfoTextSrc=src (optimize size++, -Os)else COMMONFLAGS+=-O3 InfoTextSrc=src (full optimize, -O3)endifCFLAGS+=$(COMMONFLAGS) -Wall -Werror $(INCLUDE)CFLAGS+=-D $(TypeOfMCU)CFLAGS+=-D VECT_TAB_FLASH#Commands for libs Makefileifeq ($(OptLIB),0) COMMONFLAGSlib+=-O0 InfoTextLib=libs (no optimize, -O0)else ifeq ($(OptLIB),1) COMMONFLAGSlib+=-O1 InfoTextLib=libs (optimize time+ size+, -O1)else ifeq ($(OptLIB),2) COMMONFLAGSlib+=-O2 InfoTextLib=libs (optimize time++ size+, -O2)else ifeq ($(OptLIB),s) COMMONFLAGSlib+=-Os InfoTextLib=libs (optimize size++, -Os)else COMMONFLAGSlib+=-O3 InfoTextLib=libs (full optimize, -O3)endifCFLAGSlib+=$(COMMONFLAGSlib) -Wall -Werror $(INCLUDE)CFLAGSlib+=-D $(TypeOfMCU)CFLAGSlib+=-D VECT_TAB_FLASH

linux内核模块编译-通过Makefile重命名.ko文件名和模块名

假设模块的源文件为hello.c,源码如下:

使用该文件编译内核模块。 正常情况下,Makefile文件内容如下:

执行 make 命令,生成hello.ko文件。 执行 sudo insmod hello.ko 命令,安装该模块。 执行 lsmod 命令,查看安装的模块。就会看到第一行的就是hello模块。

但是,如果想自定义模块名称为 xmodule ,而不是默认的 hello ,如何实现呢?方法如下: 在Makefile中重命名obj-m并将obj-m的依赖关系设置为原始模块(hello) 修改后的Makefile文件内容如下:

将obj-m设置为 xmodule .o,并使 xmodule .o依赖于 hello .o. 执行 make 命令后,生成 xmodule .ko, 而不是 hello .ko, 安装命令: sudo insmod xmodule.ko 查看命令: lsmod ,就会看到被安装名为 xmodule 的模块。

[Linux]编写一个简单的C语言程序,编写Makefile文件

八 环境变量 8.1 查看环境变量 $ env  显示所有的环境变量设置 $ echo $ENV_VARIABLE  显示指定环境变量的设置 例: $ echo $PATH /bin:/etc:/usr/bin:/tcb/bin 8.2 设定环境变量 $ ENV_VARIABLE=XXX;export ENV_VARIABLE 例: $ PATH=$PATH:$INFORMIXDIR/bin;export PATH  将环境变量PATH设定为原PATH值+$INFORMIXDIR/bin 8.3 取消环境变量设置 $ unset $ENV_VARIABLE 例: $ set GZJ=gzj;export GZJ  设置环境变量GZJ $ echo $GZJ gzj  显示环境变量值 $ unset $GZJ  取消环境变量GZJ的设置 $ echo $GZJ  已取消 一 makefile规则 makefile是一个make的规则描述脚本文件,包括四种类型行:目标行、命令行、宏定义行和make伪指令行(如“include”)。makefile文件中注释以“#”开头。当一行写不下时,可以用续行符“\”转入下一行。 1.1 目标行 目标行告诉make建立什么。它由一个目标名表后面跟冒号“:”,再跟一个依赖性表组成。 例: example: depfile deptarget 该目标行指出目标example与depfile和deptarget有依赖关系,如果depfile或deptarget有修改,则重新生成目标。 example1 example2 example3: deptarget1 deptarget2 depfile 该目标行指出目标名表中的example1、example2、example3这三个各自独立的目标是用相同的依赖列表和规则生成的。 clean: 空的依赖列表说明目标clean没有其他依赖关系。 目标行后续的以Tab 开始的行是指出目标的生成规则,该Tab字符不能以空格代替。例如: example.o:example.c example.h cc –c example.c 该例子指出目标example.o依赖于example.c和example.h。如果example.c或example.h其中之一改变了,就需要执行命令cc –c example.c重新生成目标example.o。 可以用文件名模式匹配来自动为目标生成依赖表,如: prog: *.c 以下是一个简单的makefile的例子: 图 1 最简单的makefile例 make使用makefile文件时,从第一个目标开始扫描。上例中的第一个目标为all,所以目标clean不会自动被执行,可以通过命令make clean来生成目标。 1.2 命令行 命令行用来定义生成目标的动作。 在目标行中分号“;”后面的文件都认为是一个命令,或者一行以Tab制表符开始的也是命令。 如在上面的makefile例中,第三行以Tab字符开始的cc命令即是一个命令行,说明要生成hello应执行的命令。也可以写成:hello:hello.o;cc –c hello –L… 一般情况下,命令行的命令会在标准输出中回显出来,如对上面的makefile执行make时,标准输出如下: cc -c hello.c cc -o hello -L/usr/X11R6/lib -L/usr/lib -lXm -lXt -lX11 hello.o cc -c hello1.c cc -o hello1 -L/usr/X11R6/lib -L/usr/lib -lXm -lXt -lX11 hello1.o 如果不希望命令本身回显,可在命令前加@字符,如在上例中不希望回显cc –c hello.c和cc –c hello1.c,可修改makefile文件如下: 图 2 抑制回显的makefile例 对该makefile文件执行make时,标准输出如下: cc -o hello -L/usr/X11R6/lib -L/usr/lib -lXm -lXt -lX11 hello.o cc -o hello1 -L/usr/X11R6/lib -L/usr/lib -lXm -lXt -lX11 hello1.o 可以看出,命令行前有@字符的不回显。 1.3 宏定义行 在makefile中,可以使用宏定义减少用户的输入,例如上例中对hello和hello1的编译选项均为“-L/usr/X11R6/lib -L/usr/lib -lXm -lXt -lX11”,此时可以用宏来代替,如: 图 3 使用宏定义的makefile例 宏定义的基本语法是: name=value 在定义宏时,次序不重要。宏不需要在使用前定义。如果一个宏定义多次,则使用最后一次的定义值。 可以使用“$”字符和“()”或“{}”来引用宏,例如: cc –o hello.o $(CCFLAGS) hello.o 也可以将一个宏赋值给另一个宏,但这样的定义不能循环嵌套,如: A=value1 B=value2 C=$(A) $(B)等价于C=value1 value2 1.4 伪指令 makefile大部分由宏定义行、命令行和目标行组成。第四种类型是make伪指令行。make伪指令没有标准化,不同的make可能支持不同的伪指令集,使得makefile有一定的不兼容性。如果要考虑移植性问题,则要避免使用make伪指令。但有一些伪指令,如include,由于使用比较多,很多不同make都提供该伪指令。 1.4.1 伪指令include 该伪指令类似C语言中的#include,它允许一次编写常用的定义并包括它。include伪指令必须在一行中,第一个元素必须是include,并且跟一个要包含的文件名,如: include default.mk 1.4.2 伪指令“#” “#”字符也是make的伪指令,它指出“#”后面的文件是注释,如: PROGNAME=test # define macro #don’t modify this 二 后缀规则 2.1 双后缀规则 在前面的makefile例中有许多重复内容,例如,生成hello和hello1的命令类似,生成hello.o和hello1.o的命令也类似,除了编译或链接的文件不一样外,其它均相同,这时,我们就可以使用后缀规则。首先看一个双后缀的例子: 图 4 使用双后缀规则的makefile例 后缀规则使用特殊的目标名“.SUFFIXES”。 第一行中.SUFFIXES的依赖表为空,用来清除原有的后缀规则,因为.SUFFIXES可以在makefile中多次使用,每一次都将新的后缀规则加入以前的后缀规则中。 第二行中指定后缀规则为“.c .o”,即表示将所有的.c文件转换为.o文件。 第三行指定将.c文件转换成.o文件的方法。$(CC)为make的预定义宏,其默认值为cc,$《为特殊的宏,代替当前的源文件,即所有要编译的.c文件。 第六行指定目标hello和hello1的生成方法。$@为特殊的宏,代替当前的目标名,即hello和hello1,$@.o即为hello.o和hello1.o。 上例介绍的是双后缀规则,即它包含两个后缀,如.c.o,用来把一个C源文件编译为目标文件。双后缀规则描述如何由第一个后缀类型的文件生成第二个后缀类型的文件,例如:.c.o规则描述如何由.c文件生成.o文件。 2.2 单后缀规则 单后缀规则描述了怎样由指定后缀的文件生成由它基名为名字的文件。例如使用单后缀规则.c,可以由hello.c和hello1.c生成hello和hello1文件。例如将前面的makefile改为: 图 5 使用单后缀规则的makefile例 由于.c后缀规则为make标准后缀规则,make为其指定了相应的命令行,所以在makefile中可以不用再指定其目标生成的具体命令行。 下表是make提供的标准后缀规则。 表 1 make标准后缀规则 后缀规则 命令行 .c $(LINK.c) –o $@ $《 $(LDLIBS) .c.ln $(LINK.c) $(POUTPUT OPTPUT OPTION) –i $《 .c.o $(COMPILE.c) $(OUTPUT OPTION) $《 .c.a $(COMPILE.c) –o $% $《 $(AR) $(ARFLAGS) $@ $% $(RM) $% 三 特殊目标 在后缀规则中使用了特殊目标.SUFFIXES,用来指定新增的后缀规则。make还提供了几个特殊目标来设置make的行为,下面为一些特殊的目标:  .IGNORE make在执行命令行时,如果返回的是错误码,make的缺省动作是停止并退出。增加该目标后,make将忽略命令行返回的错误码,并继续执行后续的操作。  .SILENT 前面已经介绍过,make在执行命令行时会回显命令行内容,在命令行前增加“@”字符将抑制该命令行的回显。 如果增加该目标,所有的命令行不再回显,相当于在每个命令行前均增加了“@”字符。  .PRECIOUS 当收到一个信号或从shell命令返回非零的错误码时,make删除它所有已建立的文件。但有些文件即使出了错误,用户也不想让make删除,这些文件可以作为.PRECIOUS目标的参数。它可以在一个makefile中出现多次,每一次都累积文件列表。  .SUFFIXES 它为makefile指定新的后缀规则,新的后缀规则作为.SUFFIXES的依赖表给出。.SUFFIXES可以在一个makefile中多次使用,每一次都将新的后缀规则加入以前的后缀规则中,如果.SUFFIXES的依赖表为空,则设置后缀规则表为空。 四 特殊的宏 为简单使用规则,make提供了几个特殊的宏:  $@ 整个当前目标名的值可以由宏“$@”来代替。  $《 当前的源文件由“$《”来代替。例如,在前面的例子中用到了$(CC) –c $《,其中的“$《”是所有要编译的.c文件。宏“$《”仅在后缀规则或.DEFAULT中有效。  $* 当前目标的基名由宏“$*”来代替。例如目标的名字是hello.o,则基名就是除去了后缀.o的hello。 以上介绍的特殊宏使用了make自身的规则,用户不可以改变。下表介绍了C中预定义的宏。 用途 宏 默认值 库文档汇编命令 AR ar ARFLAGS rv AS as ASFLAGS COMPILE.s $(AS) $(ASFLAGS) $(TARGET ARCH) C编译器命令 CC cc CFLAGS CPPFLAGS COMPILE.c $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET ARCH) –c LINK.c $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET ARCH) 链接器命令 LD ld LDFLAGS rm命令 RM rm 后缀列表 SUFFIXES .o .c .c~ .s .s~ .S .S~ .ln .f .f~ .F .F~ .l .mod .mod~ .sym .def .def~ .p .p~ .r .r~ .y .y~ .h .h~ .sh .sh~ .cps .cps~ 五 makefile的应用 当调用make时,它在当前目录下搜索文件名是“makefile”或“Makefile”的文件,并执行。 如果不想使用上述缺省文件,可以使用命令行中的“-f”来指定文件,如将编写的makefile命名为mklib,则指定为“make –f mklib”。

Linux下makefile文件的编写问题!

ifneq ($(KERNELRELEASE),)obj-m := prog.o subr.oelseKDIR := /lib/modules/2.6.18-194.el5/build(你的内核的路径,自己选择)all: make -C $(KDIR) M=$(PWD) modulesclean: rm -f *.ko *.o *.mod.o *.mod.c *.symversendifmake之后,先加载subr.ko,在加载prog.ko。祝你成功咯!

linux如何编写并使用makefile

1、先写Makefile编译出***.ko文件模板如下,保存到命名为Makefile文件里,放到你代码的同级目录下TARGET=my_proc.koLINUXDIR=/lib/modules/$(shell uname -r)/buildPWD=$(shell pwd)obj-m :=obj-m += my_proc.oall: $(TARGET)$(TARGET): $(OBJS)make -C $(LINUXDIR) SUBDIRS=$(PWD) modulesclean:rm -f modules.order Module.symvers $(TARGET) *.mod.c *.orm -rf .tmp_versions .mod* Module.markers2、make3、root权限下用命令插入模块insmod my_proc.ko4、可以用你写的应用程序打开、操作模块了5、查看模块命令lsmodcat /proc/modulesmodinfo my_proc.ko6、root下卸载模块rmmod

Linux中编写了内核模块的C源程序之后怎么编写makefile文件的内容

make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。首先,我们用一个示例来说明Makefile的书写规则。以便给大家一个感兴认识。这个示例来源于GNU的make使用手册,在这个示例中,我们的工程有8个C文件,和3个头文件,我们要写一个Makefile来告诉make命令如何编译和链接这几个文件。我们的规则是:1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。只要我们的Makefile写得够好,所有的这一切,我们只用一个make命令就可以完成,make命令会自动智能地根据当前的文件修改的情况来确定哪些文件需要重编译,从而自己编译所需要的文件和链接目标程序。一、Makefile的规则在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则。target ... : prerequisites ...command......target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。prerequisites就是,要生成那个target所需要的文件或是目标。command也就是make需要执行的命令。(任意的Shell命令)这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。说到底,Makefile的东西就是这样一点,好像我的这篇文档也该结束了。呵呵。还不尽然,这是Makefile的主线和核心,但要写好一个Makefile还不够,我会以后面一点一点地结合我的工作经验给你慢慢到来。内容还多着呢。:)二、一个示例正如前面所说的,如果一个工程有3个头文件,和8个C文件,我们为了完成前面所述的那三个规则,我们的Makefile应该是下面的这个样子的。edit : main.o kbd.o command.o display.o /insert.o search.o files.o utils.occ -o edit main.o kbd.o command.o display.o /insert.o search.o files.o utils.omain.o : main.c defs.hcc -c main.ckbd.o : kbd.c defs.h command.hcc -c kbd.ccommand.o : command.c defs.h command.hcc -c command.cdisplay.o : display.c defs.h buffer.hcc -c display.cinsert.o : insert.c defs.h buffer.hcc -c insert.csearch.o : search.c defs.h buffer.hcc -c search.cfiles.o : files.c defs.h buffer.h command.hcc -c files.cutils.o : utils.c defs.hcc -c utils.cclean :rm edit main.o kbd.o command.o display.o /insert.o search.o files.o utils.o反斜杠(/)是换行符的意思。这样比较便于Makefile的易读。我们可以把这个内容保存在文件为“Makefile”或“makefile”的文件中,然后在该目录下直接输入命令“make”就可以生成执行文件edit。如果要删除执行文件和所有的中间目标文件,那么,只要简单地执行一下“make clean”就可以了。在这个makefile中,目标文件(target)包含:执行文件edit和中间目标文件(*.o),依赖文件(prerequisites)就是冒号后面的那些 .c 文件和 .h文件。每一个 .o 文件都有一组依赖文件,而这些 .o 文件又是执行文件 edit 的依赖文件。依赖关系的实质上就是说明了目标文件是由哪些文件生成的,换言之,目标文件是哪些文件更新的。在定义好依赖关系后,后续的那一行定义了如何生成目标文件的操作系统命令,一定要以一个Tab键作为开头。记住,make并不管命令是怎么工作的,他只管执行所定义的命令。make会比较targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新,或者target不存在的话,那么,make就会执行后续定义的命令。这里要说明一点的是,clean不是一个文件,它只不过是一个动作名字,有点像C语言中的lable一样,其冒号后什么也没有,那么,make就不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令。要执行其后的命令,就要在make命令后明显得指出这个lable的名字。这样的方法非常有用,我们可以在一个makefile中定义不用的编译或是和编译无关的命令,比如程序的打包,程序的备份,等等。

Linux平台Makefile文件的编写基础篇的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于Linux平台Makefile文件的编写基础篇、Linux平台Makefile文件的编写基础篇的信息别忘了在本站进行查找哦。