⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 一个软件,从零到发布(_tar_gz).htm

📁 有关Makefile生成的全攻略
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<!-- ads -->
                        <TABLE cellSpacing=0 cellPadding=0 align=left 
                          border=0><TBODY>
                          <TR>
                            <TD></TD></TR></TBODY></TABLE><!-- ads -->作者: 
                        赵氏软体(http://chiosoft.51.net)<BR>E-mail: 
                        chiosoft@tom.com<BR>※转贴请注明出处※<BR><BR>  本文教你如何使用autoconf、automake等来制作一个以源代码形式(.tar.gz)发布的软件、并可在执行configure时使用自定义参数。(其实这是我自己的一份笔记^_^)<BR><BR><BR><B>一、概述和基础知识</B><BR><BR>  在Linux下得到一个以源代码形式发布的包(一般为.tar.gz或.tar.bz2格式),我们可以用 
                        ./confiugure、make、make 
                        install来编译安装,其中在运行./configure的时候还可以根据自己的需要加入不同的参数(可用./configure 
                        --help来查看参数表)。<BR><BR>  先说说执行./configure后会生成什么东西?运行后系统会根据用户的实际情况生成config.h和多个Makefile。其中Makefile是运行make时所用的模板;而config.h则会以宏(Marco)的形式记录用户的自定义参数,编译器可以根据config.h来对源代码进行预编译(pre-compile),从而生成个性化的执行档。<BR><BR><BR><B>二、我们的“软件”</B><BR><BR>  现在我们可以动手设计一个自己的“软件”了,为了更切合实际,将使用多个源程序,首先建立一个目录tt,用来放我们的东西,然后在tt下建立一个src目录,一般来说源代码都放在src中(好像已经成为一个不成文的规矩了:P)。整体架构如下:<BR><FONT 
                        class=CodeSize>  &lt;tt&gt;<BR>   |-configure.in<BR>   |-Makefile.am<BR>   |-acconfig.h<BR>   |-&lt;src&gt;<BR>     |-tt.c<BR>     |-qq.c<BR>     |-qq.h<BR>     |-Makefile.am<BR><BR></FONT>※说明:<BR>1. 
                        <FONT 
                        color=#c00000>configure.in</FONT> 这是最重要的文档,整个安装过程都靠它来主导。<BR>2. 
                        <FONT 
                        color=#c00000>Makefile.am</FONT> automake会根据它来生成Makefile.in,再由./configure 
                        把Makefile.in变成最终的Makefile,一般来说在顶级目录和各个子目录都应该有一个Makefile.am<BR>3. 
                        <FONT 
                        color=#c00000>acconfig.h</FONT> autoheader会根据它来生成config.h.in,再由./configure 
                        把config.h.in变成最终的config.h<BR>4. <FONT color=#c00000>tt.c 
                        qq.c 
                        qq.h</FONT> 这是我们的源程序。<BR><BR>※源代码内容:(代码中绿色部份就是用来实现个性化编译)<BR>
                        <CENTER>
                        <TABLE width="90%">
                          <TBODY>
                          <TR>
                            <TD align=middle bgColor=#000000>
                              <TABLE cellSpacing=3 width="100%">
                                <TBODY>
                                <TR>
                                <TD bgColor=#ffffe0><FONT 
                                class=CodeSize><B>tt.c</B><BR><BR>#include 
                                &lt;stdio.h&gt;<BR>#include 
                                &lt;qq.h&gt;<BR><BR><FONT color=#008000>#ifdef 
                                HAVE_CONFIG_H<BR>#include 
                                &lt;config.h&gt;<BR>#endif<BR></FONT><BR>int 
                                main(void)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;int a 
                                = 23;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;printf( 
                                "Hello, I am teacher(%d), pls tell me your 
                                names!\n", a );<BR><BR><FONT 
                                color=#008000>&nbsp;&nbsp;&nbsp;&nbsp;#ifdef 
                                POPO<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf("My name 
                                is 
                                PoPo!\n");<BR>&nbsp;&nbsp;&nbsp;&nbsp;#endif<BR></FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;qq();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;return 
                                0;<BR>}<BR><BR></FONT></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>
                        <TABLE width="90%">
                          <TBODY>
                          <TR>
                            <TD align=middle bgColor=#000000>
                              <TABLE cellSpacing=3 width="100%">
                                <TBODY>
                                <TR>
                                <TD bgColor=#ffffe0><FONT 
                                class=CodeSize><B>qq.c</B><BR><BR>#include 
                                &lt;stdio.h&gt;<BR>#include 
                                &lt;qq.h&gt;<BR><BR><FONT color=#008000>#ifdef 
                                HAVE_CONFIG_H<BR>#include 
                                &lt;config.h&gt;<BR>#endif<BR></FONT><BR>void 
                                qq(void)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf("My 
                                name is QQ\n");<BR><BR><FONT 
                                color=#008000>&nbsp;&nbsp;&nbsp;&nbsp;#ifdef 
                                POPO<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf("QQ: Hey 
                                PoPo, long time no 
                                see.\n");<BR>&nbsp;&nbsp;&nbsp;&nbsp;#endif<BR></FONT>}<BR><BR></FONT></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>
                        <TABLE width="90%">
                          <TBODY>
                          <TR>
                            <TD align=middle bgColor=#000000>
                              <TABLE cellSpacing=3 width="100%">
                                <TBODY>
                                <TR>
                                <TD bgColor=#ffffe0><FONT 
                                class=CodeSize><B>qq.h</B><BR><BR>#ifndef 
                                __QQ__<BR>#define __QQ__<BR><BR>void 
                                qq(void);<BR><BR>#endif<BR><BR></FONT></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR></CENTER>※运行流程:<BR> 1. 
                        首先老师来点名。<BR> 2. 如果PoPo有来的话,将会报出自己的名字。<BR> 3. 
                        接著轮到QQ报到,如果PoPo有来的话,QQ会向PoPo问好。<BR><BR>  显然易见,PoPo是否出席,完全取决于POPO这个宏(Macro)有否被定义,我们只要在编译前决定要不要定义它,就能实现不同的效果。<BR><BR>  如果config.h存在的话,编译时Makefile会把宏HAVE_CONFIG_H传给编译器,所以如果没有定义HAVE_CONFIG_H 
                        的话,我们的程序不应该把config.h 
                        include进去。<BR><BR><BR><B>三、制作流程</B><BR><BR>请按照以下的执行顺序一步一步做:<BR><BR><FONT 
                        color=#ff0000>第一步 编写configure.in</FONT><BR><BR>  生成configure.in的方法有两个,一个是自己从零开始写,另一个方法是用autoscan,执行autoscan后会生成configure.scan,其中包含了一些模板内容,使用时只要把名字改成.in就可以。<BR><BR>  configure.in中使用的命令有两种,一种是以AC开头,表示是由autoconf提供,另一种是以AM开头,代表由automake提供。<BR><BR>  在configure.in我们可以完成很多检测动作,比如检查编译所需的程式、头文件、库等等,总之功能是十分强大,不过我们这里只检测了编译器和头文件,详细用法请看 
                        <A href="http://www.gnu.org/manual/manual.html" 
                        target=_new>GNU Manuals 
                        Online</A><BR><BR>  以"dnl"为首的行为注释行(代码中绿色部份)。<BR><BR>
                        <CENTER>
                        <TABLE width="90%">
                          <TBODY>
                          <TR>
                            <TD align=middle bgColor=#000000>
                              <TABLE cellSpacing=3 width="100%">
                                <TBODY>
                                <TR>
                                <TD bgColor=#ffffe0><FONT 
                                class=CodeSize><B>configure.in</B><BR><BR><FONT 
                                color=#008000>dnl 
                                初始化autoconf,参数为入口函数所在的文件<BR></FONT>AC_INIT(src/tt.c)<BR><BR><FONT 
                                color=#008000>dnl 
                                初始化automake,参数为软件名称及版本号<BR></FONT>AM_INIT_AUTOMAKE(tt, 
                                0.1.0)<BR><BR><FONT color=#008000>dnl 
                                告诉automake我们所用的配置文件,一般为config.h<BR></FONT>AM_CONFIG_HEADER(config.h)<BR><BR><FONT 
                                color=#008000>dnl 
                                这里是实现自定义参数的部份,见下面的说明<BR></FONT>AC_ARG_ENABLE(popo, 
                                [ --enable-popo PoPo is 
                                present],,enable_popo=no)<BR>if test 
                                "$enable_popo" = yes ; 
                                then<BR>&nbsp;&nbsp;&nbsp;&nbsp;echo "PoPo is 
                                here!"<BR>&nbsp;&nbsp;&nbsp;&nbsp;AC_DEFINE(POPO)<BR>else<BR>&nbsp;&nbsp;&nbsp;&nbsp;echo 
                                "PoPo isn't here!"<BR>fi<BR><BR><FONT 
                                color=#008000>dnl 
                                检测编译器<BR></FONT>AC_PROG_CC<BR><BR><FONT 
                                color=#008000>dnl 检测Standard 
                                C的头文件<BR></FONT>AC_HEADER_STDC<BR><BR><FONT 
                                color=#008000>dnl 
                                输出文件,一般来说顶级目录和各子目录都应有Makefile输出<BR></FONT>AC_OUTPUT(Makefile 
                                src/Makefile)<BR><BR></FONT></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR></CENTER>  ./configure的自定义参数有两种,一种是开关式(--enable-XXX或--disable-XXX),另一种是开放式,即后面要填入一串字符(--with-XXX=yyyy)参数。<BR>  上述代码中用的是开关式,第一个参数是参数名,第二个是说明(执行"./configure 
                        --help"后所显示出来的内容),最后一个参数是默认值。一般来说默认值和用户提示应该是互斥的,即默认值是no的话,应提示用户用enable进行修改,反之亦然。<BR>  从上面的代码中可以看到,如果$enable_popo为yes的话,就用AC_DEFINE来定义POPO这个宏(Macro),否则就不定义,我们在这里所使用到的宏,一定要在acconfig.h中声明。<BR><BR><FONT 
                        color=#ff0000>第二步 运行aclocal</FONT> 在tt目录下运行aclocal,将会生成aclocal.m4。<BR><BR><FONT 
                        color=#ff0000>第三步 编写acconfig.h</FONT><BR><BR>  在configure.in中使用到的宏(Macro),都应该在这个文件声明,一般用#undef来声明。<BR>
                        <CENTER>
                        <TABLE width="90%">
                          <TBODY>
                          <TR>
                            <TD align=middle bgColor=#000000>
                              <TABLE cellSpacing=3 width="100%">
                                <TBODY>
                                <TR>
                                <TD bgColor=#ffffe0><FONT 
                                class=CodeSize><B>acconfig.h</B><BR><BR>#undef 
                                POPO<BR><BR></FONT></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR></CENTER><FONT 
                        color=#ff0000>第四步 运行autoheader</FONT><BR><BR>  运行autoheader后会根据configure.in、acconfig.h和系统预设的acconfig.h来生成config.h.in。<BR><BR><FONT 
                        color=#ff0000>第五步 编写Makefile.am</FONT><BR><BR>  一般来说,在顶级目录和各子目录都应有一个Makefile.am。<BR><BR>
                        <CENTER>
                        <TABLE width="90%">
                          <TBODY>
                          <TR>
                            <TD align=middle bgColor=#000000>
                              <TABLE cellSpacing=3 width="100%">
                                <TBODY>
                                <TR>
                                <TD bgColor=#ffffe0><FONT 
                                class=CodeSize><B>Makefile</B><BR><BR>AUTOMAKE_OPTIONS 
                                = foreign<BR>SUBDIRS = 
                                src<BR><BR></FONT></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></CENTER>  第一行是告诉automake不要检测目录中是否存在AUTHORS、README等文件。<BR>  第二行是告诉automake处理src这个子目录。<BR><BR>
                        <CENTER>
                        <TABLE width="90%">
                          <TBODY>
                          <TR>
                            <TD align=middle bgColor=#000000>
                              <TABLE cellSpacing=3 width="100%">
                                <TBODY>
                                <TR>
                                <TD bgColor=#ffffe0><FONT 
                                class=CodeSize><B>src/Makefile</B><BR><BR>AUTOMAKE_OPTIONS 
                                = foreign<BR>bin_PROGRAMS = tt<BR>tt_SOURCES = 
                                tt.c qq.c 
                              qq.h<BR><BR></FONT></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></CENTER>  第一行作用同前。<BR>  第二行是目标执行档的名称。<BR>  第三行是生成tt这个执行档所需的所有源程序和头文件名称。<BR><BR><FONT 
                        color=#ff0000>第六步 运行automake</FONT><BR><BR>  接著可以执行automake了,在命令行下输入<BR>    automake 
                        -a 和<BR>    automake -a src/Makefile<BR>  使用"automake 
                        -a"或"automake 
                        --add-missing",会自动将install.sh、mkinstalldirs等文件补齐,否则会出错,切记!<BR><BR><FONT 
                        color=#ff0000>第七步 运行autoconf</FONT><BR><BR>  最后,可以执行autoconf了,完成后将会生成最终的configure!<BR><BR><BR><B>四、编译&amp;测试</B><BR><BR>  用默认值编译: 

                        <CENTER>
                        <TABLE width="90%">
                          <TBODY>
                          <TR>
                            <TD align=middle bgColor=#000000>
                              <TABLE cellSpacing=3 width="100%">
                                <TBODY>
                                <TR>
                                <TD bgColor=#f7dfb5><FONT 
                                class=CodeSize><B>[root@chiosoft tt]# 
                                ./configure</B><BR>Checking for ......<BR>PoPo 
                                isn't here!<BR>Checking for 
                                ......<BR><BR><B>[root@chiosoft tt]# 
                                make</B><BR>......<BR><BR><B>[root@chiosoft tt]# 
                                src/tt</B><BR>Hello, I am teacher(23), pls tell 
                                me your names!<BR>My name is 
                                QQ<BR><BR></FONT></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></CENTER>  默认状态下,我们没有定义宏POPO,所以./configure时输出"PoPo 
                        isn't here!",运行时也只有QQ来报到。<BR><BR>  再看看这个: 
                        <CENTER>
                        <TABLE width="90%">
                          <TBODY>
                          <TR>
                            <TD align=middle bgColor=#000000>
                              <TABLE cellSpacing=3 width="100%">
                                <TBODY>
                                <TR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -