关于Makefile的生成

多核多进程并发条件下Linux驱动开发的研究(一)关于Makefile的生成(综合网上资源)

问题来源:最近的一个研究主题:关于多核多进程并发条件下的Linux驱动开发的研究。

                 一、 网上的博客文章《 老手经验:Linux驱动开发学习步骤》(http://naiquan-hu.javaeye.com/blog/497741)(内容见附1)

                        中提及makefile的编写

                二、本人的本科毕设中imote2上实现的nesC实验中,曾涉及到了Makefile的编写(内容见附2)

                三、在《Linux设备驱动程序》书第二章构造和运行模块中编译和装载中helloworld的相关Makefile(内容见附3)

问题解决方法(技巧):Linux下Makefile的automake生成全攻略(http://www.yesky.com/120/1865620.shtml)

       目标:Linux程序开发中,make命令来编译自己写的程序,可以手工写,但可使用autoconf和automake两个工具来帮助我们自动地生成符合自由软件惯例的Makefile。 这样就可以像常见的GNU程序一样,只要使用“./configure”,“make”,“make instal”就可以把程序安装到Linux系统中去了。

      适合人群:适合想做开放源代码软件的程序开发人员,又或如果你只是自己写些小的Toy程序

      整理:

     makefile用于自动编译和链接的。

     由automake根据一个宏文件生成Makefile.in。 

     由autoconf根据一个宏文件生成configure,再使用configure根据Makefile.in来生成Makefile。

     要编写的文件:一个c文件(如:helloworld.c)

                             configure.inconfigure.in:内容是一些宏定义,这些宏经autoconf处理后会变成检查系统特性、环境变量、软件必须的参                                                                         数的shell脚本。

                             Makefile.am:定义的宏和目标,会指导automake生成指定的代码。例如,宏bin_PROGRAMS将导致编译和连接的目标被                                                        生成。

      执行的命令:aclocal;autoconf;automake --add-missing;./configure;make;./helloworld

       autoconf 是用来生成自动配置软件源代码脚本(configure)的工具。configure脚本能独立于autoconf运行,且在运行的过程中,不需要用户的干预。

   要生成configure文件,你必须告诉autoconf如何找到你所用的宏。方式是使用aclocal程序来生成你的aclocal.m4。
   aclocal根据configure.in文件的内容,自动生成aclocal.m4文件。aclocal是一个perl 脚本程序,它的定义是:“aclocal - create aclocal.m4 by scanning configure.ac”。

      执行configure生成Makefile

      使用Makefile编译代码

Linux下Makefile的automake生成全攻略(http://www.yesky.com/120/1865620.shtml)

 一、Makefile的介绍

       Makefile是用于自动编译和链接的,一个工程有很多文件组成,每一个文件的改变都会导致工程的重新链接,但是不是所有的文件都需要重新编译,Makefile中纪录有文件的信息,在make时会决定在链接的时候需要重新编译哪些文件。
       Makefile的宗旨就是:让编译器知道要编译一个文件需要依赖其他的哪些文件。当那些依赖文件有了改变,编译器会自动的发现最终的生成文件已经过时,而重新编译相应的模块。
  Makefile的基本结构不是很复杂,但当一个程序开发人员开始写Makefile时,经常会怀疑自己写的是否符合惯例,而且自己写的Makefile经常和自己的开发环境相关联,当系统环境变量或路径发生了变化后,Makefile可能还要跟着修改。这样就造成了手工书写Makefile的诸多问题,automake恰好能很好地帮助我们解决这些问题。
  使用automake,程序开发人员只需要写一些简单的含有预定义宏的文件,由autoconf根据一个宏文件生成configure,由automake根据另一个宏文件生成Makefile.in,再使用configure依据Makefile.in来生成一个符合惯例的Makefile。下面我们将详细介绍Makefile的automake生成方法。

  二、使用的环境

  本文所提到的程序是基于Linux发行版本:Fedora Core release 1,它包含了我们要用到的autoconf,automake。              

三、从helloworld入手

       我们从大家最常使用的例子程序helloworld开始。

  下面的过程如果简单地说来就是:

  新建三个文件:

   helloworld.c
   configure.in
   Makefile.am

  然后执行:

aclocal; autoconf; automake --add-missing; ./configure; make; ./helloworld
  就可以看到Makefile被产生出来,而且可以将helloworld.c编译通过。

  很简单吧,几条命令就可以做出一个符合惯例的Makefile,感觉如何呀。

  现在开始介绍详细的过程:

  1、建目录

  在你的工作目录下建一个helloworld目录,我们用它来存放helloworld程序及相关文件,如在/home/my/build下:

$ mkdir helloword
$ cd helloworld
  2、 helloworld.c

  然后用你自己最喜欢的编辑器写一个hellowrold.c文件,如命令:vi helloworld.c。使用下面的代码作为helloworld.c的内容。

int main(int argc, char** argv)
{
printf("Hello, Linux World!\n");
return 0;
}
  完成后保存退出。

  现在在helloworld目录下就应该有一个你自己写的helloworld.c了。

  3、生成configure

  我们使用autoscan命令来帮助我们根据目录下的源代码生成一个configure.in的模板文件。

  命令:

$ autoscan
$ ls
configure.scan helloworld.c
  执行后在hellowrold目录下会生成一个文件:configure.scan,我们可以拿它作为configure.in的蓝本。

  现在将configure.scan改名为configure.in,并且编辑它,按下面的内容修改,去掉无关的语句:

============================configure.in内容开始=========================================
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_INIT(helloworld.c)
AM_INIT_AUTOMAKE(helloworld, 1.0)

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.
AC_OUTPUT(Makefile)
============================configure.in内容结束=========================================
  然后执行命令aclocal和autoconf,分别会产生aclocal.m4及configure两个文件:

$ aclocal 
$ls 
aclocal.m4 configure.in helloworld.c 
$ autoconf 
$ ls 
aclocal.m4 autom4te.cache configure configure.in helloworld.c
  大家可以看到configure.in内容是一些宏定义,这些宏经autoconf处理后会变成检查系统特性、环境变量、软件必须的参数的shell脚本。

  autoconf 是用来生成自动配置软件源代码脚本(configure)的工具。configure脚本能独立于autoconf运行,且在运行的过程中,不需要用户的干预。

  要生成configure文件,你必须告诉autoconf如何找到你所用的宏。方式是使用aclocal程序来生成你的aclocal.m4。

  aclocal根据configure.in文件的内容,自动生成aclocal.m4文件。aclocal是一个perl 脚本程序,它的定义是:“aclocal - create aclocal.m4 by scanning configure.ac”。

  autoconf从configure.in这个列举编译软件时所需要各种参数的模板文件中创建configure。

  autoconf需要GNU m4宏处理器来处理aclocal.m4,生成configure脚本。

  m4是一个宏处理器。将输入拷贝到输出,同时将宏展开。宏可以是内嵌的,也可以是用户定义的。除了可以展开宏,m4还有一些内建的函数,用来引用文件,执行命令,整数运算,文本操作,循环等。m4既可以作为编译器的前端,也可以单独作为一个宏处理器。           

 4、新建Makefile.am

  新建Makefile.am文件,命令:

$ vi Makefile.am
  内容如下:

AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=helloworld
helloworld_SOURCES=helloworld.c
  automake会根据你写的Makefile.am来自动生成Makefile.in。

  Makefile.am中定义的宏和目标,会指导automake生成指定的代码。例如,宏bin_PROGRAMS将导致编译和连接的目标被生成。

  5、运行automake

  命令:

$ automake --add-missing
configure.in: installing `./install-sh'
configure.in: installing `./mkinstalldirs'
configure.in: installing `./missing'
Makefile.am: installing `./depcomp'
  automake会根据Makefile.am文件产生一些文件,包含最重要的Makefile.in。

  6、执行configure生成Makefile

$ ./configure 
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... 
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ANSI C... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands
$ ls -l Makefile
-rw-rw-r-- 1 yutao yutao 15035 Oct 15 10:40 Makefile
  你可以看到,此时Makefile已经产生出来了。

  7、使用Makefile编译代码

$ make
if gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -

DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"helloworld\" -DVERSION=\"1.0\" 

-I. -I. -g -O2 -MT helloworld.o -MD -MP -MF ".deps/helloworld.Tpo" \
-c -o helloworld.o `test -f 'helloworld.c' || echo './'`helloworld.c; \
then mv -f ".deps/helloworld.Tpo" ".deps/helloworld.Po"; \
else rm -f ".deps/helloworld.Tpo"; exit 1; \
fi
gcc -g -O2 -o helloworld helloworld.o
  运行helloworld

$ ./helloworld 
Hello, Linux World!
  这样helloworld就编译出来了,你如果按上面的步骤来做的话,应该也会很容易地编译出正确的helloworld文件。你还可以试着使用一些其他的make命令,如make clean,make install,make dist,看看它们会给你什么样的效果。感觉如何?自己也能写出这么专业的Makefile,老板一定会对你刮目相看。

附1:(网上摘录)

          1. 学会写简单的makefile

          2. 编一应用程序,可以用makefile跑起来

          3. 学会写驱动的makefile

          4. 写一简单char驱动,makefile编译通过,可以insmod, lsmod, rmmod. 在驱动的init函数里打印hello world, insmod后应该能够通过dmesg看到输出。

          5. 写一完整驱动, 加上read, write, ioctl, polling等各种函数的驱动实现。 在ioctl里完成从用户空间向内核空间传递结构体的实现。

          6. 写一block驱动, 加上read,write,ioctl,poll等各种函数实现。

          7. 简单学习下内存管理, 这个是最难的,明白各种memory alloc的函数实现细节。这是linux开发的基本功。

          8. 学习锁机制的应用,这个不是最难的但是最容易犯错的,涉及到很多同步和并发的问题。

          9. 看内核中实际应用的驱动代码。 你会发现最基本的你已经知道了, 大的框架都是一样的, 无非是read, write, ioctl等函数的实现, 但里面包含了很多很多细小的实现细节是之前不知道的。 这时候就要考虑到很多别的问题而不仅仅是基本功能的实现。

推荐您看2.6.20中integrated的一个驱动 kvm,记得是在driver/lguest下,很好玩的, 就是linux下的虚拟机驱动,代码不长,但功能强大。有能力的可以自己写一操作系统按照要求做成磁盘镜像加载到虚拟机中, 然后客户机可以有自己的4G虚拟地址空间。

          10. 看完驱动欢迎您进入Linux kernel学习中来。

          最简单的方法,跟着ldd(linux devive driver)做一遍。

附2:Makefile文件(imote2中用到的)

       COMPONENT=ProcessNode
       PFLAGS += -DCC2420_DEF_CHANNEL=22
       include ../Makerules

附3:Helloworld模块

        #include

        #include

        MODULE_LICENSE("Dual BSD/GPL");//特殊宏MODULE_LICENSE来告诉内核,该模块采用自由许可证;如果没有这样的声明,内核在装载该模块时会产生抱怨

    

      static int hello_init(void)//模块被装载到内核时调用

      {

      printk(KERN_ALERT"Hello,world.\n");//KERN_ALERT定义了这条消息的优先级(优先级只是个字符串,如<1>)

      return 0;

        }

      static void hello_exit(void)//模块被移除时调用

     {

         printk(KERN_ALERT"Goodbye,cruel world\n");

     }

    module_init(hello_init);//使用了内核的特殊宏来表示hello_init扮演的角色

    module_exit(hello_exit);//使用了内核的特殊宏来表示hello_exit扮演的角色

      下面为其makefile内容:

       obj-m :=hello.o

     说明有一个模块要从目标文件hello.o中构造,而从该目标文件中构造的模块名称为hello.ko

     如果我们要构造的模块名称为:module.ko,并由两个源文件生成(比如file1.c和file2.c)

     则makefile如下编写:

      obj-m :=module.o

     module-objs :=file1.o file2.o

你可能感兴趣的:(Linux)