mirror of
https://github.com/beyondx/Notes.git
synced 2026-02-03 02:15:15 +08:00
update ZIM
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*~
|
||||
auto/
|
||||
@@ -1,4 +1 @@
|
||||
* GCC 与 Glibc的关系
|
||||
GCC与Glibc是相互依赖的关系:部分链接的GCC在加载时需要Glibc提供的目标对象符号。
|
||||
GCC运行时库文件也需要Glibc提供的符号。同时Glibc提供的crt1.o,crti.o,crtn.o等也
|
||||
依赖GCC的crtbegin.o, crtend.o等提供的符号。
|
||||
|
||||
|
||||
BIN
Org/Tool-Chain.pdf
Normal file
BIN
Org/Tool-Chain.pdf
Normal file
Binary file not shown.
42
Org/Tool-Chain.tex
Normal file
42
Org/Tool-Chain.tex
Normal file
@@ -0,0 +1,42 @@
|
||||
% Created 2013-01-07 Mon 12:24
|
||||
\documentclass[11pt]{article}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{fixltx2e}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{longtable}
|
||||
\usepackage{float}
|
||||
\usepackage{wrapfig}
|
||||
\usepackage{soul}
|
||||
\usepackage{textcomp}
|
||||
\usepackage{marvosym}
|
||||
\usepackage{wasysym}
|
||||
\usepackage{latexsym}
|
||||
\usepackage{amssymb}
|
||||
\usepackage{hyperref}
|
||||
\tolerance=1000
|
||||
\providecommand{\alert}[1]{\textbf{#1}}
|
||||
|
||||
\title{Tool-Chain}
|
||||
\author{}
|
||||
\date{\today}
|
||||
\hypersetup{
|
||||
pdfkeywords={},
|
||||
pdfsubject={},
|
||||
pdfcreator={Emacs Org-mode version 7.8.11}}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\maketitle
|
||||
|
||||
\setcounter{tocdepth}{3}
|
||||
\tableofcontents
|
||||
\vspace*{1cm}
|
||||
\section{GCC 与 Glibc的关系}
|
||||
\label{sec-1}
|
||||
|
||||
GCC与Glibc是相互依赖的关系:部分链接的GCC在加载时需要Glibc提供的目标对象符号。
|
||||
GCC运行时库文件也需要Glibc提供的符号。同时Glibc提供的crt1.o,crti.o,crtn.o等也
|
||||
依赖GCC的crtbegin.o, crtend.o等提供的符号。
|
||||
|
||||
\end{document}
|
||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
||||
[History]
|
||||
list=[["Utils:\u5de5\u5177\u94fe:autoconf---automake:Autoconf\u5b66\u4e60\u7b14\u8bb0",7575,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b",849,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake",3328,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b",1475,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake",3328,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b",3346,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake",3328,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b",65,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b:demo.c",40,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b:foo.c",39,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b:demo.c",1314,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b:foo.c",135,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b:demo.c",1314,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b",5599,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake",3328,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b",10803,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:Autoconf\u5b66\u4e60\u7b14\u8bb0",7575,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b:foo.c",135,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b:autoreconf",2682,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:Autoconf\u5b66\u4e60\u7b14\u8bb0",7731,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:autoconf\u8f6f\u4ef6\u5305",698,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:Autoconf\u5b66\u4e60\u7b14\u8bb0",7731,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:autoconf\u8f6f\u4ef6\u5305",130,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:Autoconf\u5b66\u4e60\u7b14\u8bb0",873,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:Autotools\u4e0a\u624b\u6307\u5357",276,null]]
|
||||
list=[["Utils:\u5de5\u5177\u94fe:libtool:libtool\u7684\u4f5c\u7528\u53ca\u5e94\u7528",164,null],["Utils:\u5de5\u5177\u94fe:autotut-Using GNU autoconf-automake-autoheader",57108,null],["Utils:\u5de5\u5177\u94fe:pkgconfig",0,null],["Utils:\u5de5\u5177\u94fe:pkgconfig:linux\u91cc\u547d\u4ee4pkg-config\u5de5\u5177\u7684\u4f7f\u7528",0,null],["Utils:\u5de5\u5177\u94fe:pkgconfig",5545,null],["Utils:\u5de5\u5177\u94fe:pkgconfig:Makefile\u597d\u52a9\u624b\uff1apkgconfig",1740,null],["Utils:\u5de5\u5177\u94fe:pkgconfig",5545,null],["Utils:\u5de5\u5177\u94fe:autotut-Using GNU autoconf-automake-autoheader",57108,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:Is your build environment sane \uff1f",162,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:Autotools\u4e0a\u624b\u6307\u5357",7212,null],["Utils:\u5de5\u5177\u94fe:gcc&g++",0,null],["Utils:\u5de5\u5177\u94fe:libtool",6567,null],["Utils:\u5de5\u5177\u94fe:libtool:libtool\u7684\u4f5c\u7528\u53ca\u5e94\u7528",164,null],["Utils:\u5de5\u5177\u94fe:\u4f7f\u7528GNU Autotools\u81ea\u52d5\u7de8\u8b6f\u9805\u76ee",155,null],["Utils:\u5de5\u5177\u94fe:libtool:libtool\u7684\u4f5c\u7528\u53ca\u5e94\u7528",164,null],["Utils:\u5de5\u5177\u94fe:libtool",6350,null],["Utils:\u5de5\u5177\u94fe:libtool:libtool\u7684\u4f5c\u7528\u53ca\u5e94\u7528",315,null],["Utils:emacs:dired",3523,null],["Research:Error Notes:\u7f16\u8bd1\u9519\u8bef:libnl",4258,null],["Utils:Graphviz",0,null],["Utils:Graphviz:Graphviz\u4ecb\u7ecd",0,null],["Utils:emacs:gnus",3181,null],["Research:Error Notes:\u7f16\u8bd1\u9519\u8bef",0,null],["Research:Error Notes:\u7f16\u8bd1\u9519\u8bef:libnl",4528,null],["Research:Error Notes:\u7f16\u8bd1\u9519\u8bef:busybox",2449,null]]
|
||||
current=24
|
||||
recent=[["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u56fe\u89e3autoscan\u3001aclocal\u3001autoheader\u3001automake\u3001autoconf\u3001configure\u3001make",0,null],["Utils:\u5de5\u5177\u94fe:automake\u53d8\u91cf",0,null],["Utils:\u5de5\u5177\u94fe:autotut-Using GNU autoconf-automake-autoheader",0,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b:demo.c",1314,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake",3328,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b",10803,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b:foo.c",135,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:\u5b9e\u4f8b:autoreconf",2682,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:Autoconf\u5b66\u4e60\u7b14\u8bb0",873,null],["Utils:\u5de5\u5177\u94fe:autoconf---automake:Autotools\u4e0a\u624b\u6307\u5357",276,null]]
|
||||
recent=[["Utils:\u5de5\u5177\u94fe:\u4f7f\u7528GNU Autotools\u81ea\u52d5\u7de8\u8b6f\u9805\u76ee",155,null],["Utils:\u5de5\u5177\u94fe:libtool",6350,null],["Utils:\u5de5\u5177\u94fe:libtool:libtool\u7684\u4f5c\u7528\u53ca\u5e94\u7528",315,null],["Utils:emacs:dired",3523,null],["Utils:Graphviz",0,null],["Utils:Graphviz:Graphviz\u4ecb\u7ecd",0,null],["Utils:emacs:gnus",3181,null],["Research:Error Notes:\u7f16\u8bd1\u9519\u8bef",0,null],["Research:Error Notes:\u7f16\u8bd1\u9519\u8bef:libnl",1365,null],["Research:Error Notes:\u7f16\u8bd1\u9519\u8bef:busybox",2449,null]]
|
||||
|
||||
[MainWindow]
|
||||
windowsize=[1278,779]
|
||||
@@ -50,7 +50,7 @@ calendar_expanded=False
|
||||
[InsertImageDialog]
|
||||
windowsize=[1280,749]
|
||||
attach_inserted_images=False
|
||||
last_image_folder=/home/geekard/Notes/Zim/Utils/gdb/gdb_debugging
|
||||
last_image_folder=/home/geekard/Notes/Zim/Utils/\u5de5\u5177\u94fe/\u4f7f\u7528GNU_Autotools\u81ea\u52d5\u7de8\u8b6f\u9805\u76ee
|
||||
|
||||
[InsertLinkDialog]
|
||||
windowsize=[328,156]
|
||||
|
||||
@@ -9,11 +9,10 @@ dired 是 Emacs 自带的文件管理器,操作非常方便,再加上一些
|
||||
===== Mark & Flag =====
|
||||
|
||||
dired 最方便的一点就是可以**对许多文件进行标记,并进行批量操作**。标记的方法有很多,最普通的标记就是 __d __为当前文件贴上删除标签,之后可以使用 __x__ 来真正删除所有贴上删除标签的文件。
|
||||
dired 还提供了许多预定义的方便的标记操作(当使用__ C-u 传递一个前缀参数时,他们执行相反操作__,即去掉标记),例如:
|
||||
|
||||
通常这些命令可以方便地帮你清理垃圾,如果还不满意,可以使用__ % d __REGEXP <RET> 来输入自己的正则表达式,匹配到的文件会被贴上删除标签。
|
||||
|
||||
当然,能用的标签并不止是 __D (即删除标签)__,几乎任何一个字符都可以使用(但需要通过转换,默认的为D和*标签),不过__最常用的还是 *__ , m 命令即是以 * 标记当前文件。同样,dired 提供了很多方便的标记操作(这些命令在传递一个前缀参数的时候都会执行相反的操作,例如 C-u * * 会去掉所有可执行文件的标记):
|
||||
当然,能用的标签并不止是 __D (即删除标签)__,几乎任何一个字符都可以使用(但需要通过转换,默认的为D和*标签),不过__最常用的还是 *__ , m 命令即是以 * 标记当前文件。同样,dired 提供了很多方便的标记操作(这些命令在传递一个前缀参数C-u的时候都会执行__相反__的操作,例如 C-u * * 会去掉所有可执行文件的标记):
|
||||
|
||||
dired 可以使用更多的字符进行标记,只是没有提供相应的快捷键操作而已,你可以先以 * 标记,然后使用 * c OLD-MARKCHAR NEW-MARKCHAR 来把 * 标记变换成其他标记,几乎任何字符(当然不包括中文这种多字节的字符)都可以作为标记,不过空格被特殊对待,用于表示所有未标记的文件。
|
||||
|
||||
@@ -34,9 +33,9 @@ dired 还提供了许多预定义的方便的标记操作(当使用__ C-u 传递
|
||||
|
||||
dired 内建了很多文件操作,对于操作的文件有一个统一的约定,按照顺序是:
|
||||
|
||||
__如果你通过 C-u 传递一个前缀参数 N ,那么它对从当前行开始的 N 行执行操作( N 也可以是负数)。__
|
||||
__ 如果有被标记为 * 的文件,则以这些文件为操作对象。__
|
||||
__ 只对当前光标所在的文件进行操作。__
|
||||
* __如果你通过 C-u 传递一个前缀参数 N ,那么它对从当前行开始的 N 行执行操作( N 也可以是负数)。__
|
||||
* __如果有被标记为 * 的文件,则以这些文件为操作对象。__
|
||||
* __只对当前光标所在的文件进行操作。__
|
||||
|
||||
这些命令全部__绑定到大写字母__上,记忆也非常方便:
|
||||
|
||||
@@ -65,7 +64,7 @@ __ 只对当前光标所在的文件进行操作。__
|
||||
以上命令的标记为D
|
||||
a 在当前buffer打开目录(默认是在新的buffer打开目录)
|
||||
i 在当前buffer尾部打开目录,并设置标记
|
||||
k 隐藏标记为*的文件
|
||||
k 隐藏标记为__*__的文件
|
||||
o 在新buffer中打开当前文件,并将光标移到其中
|
||||
q 关闭当前窗口(不是文件编辑窗口)
|
||||
n 下移一行
|
||||
@@ -89,41 +88,35 @@ __ 只对当前光标所在的文件进行操作。__
|
||||
__w 复制文件名,如果通过 C-u 传递一个前缀参数 0 ,则复制决定路径名,如果只是 C-u 则复制相对于 dired 当前目录的相对路径。__
|
||||
I 把当前文件以 info 文档的格式打开。
|
||||
N 把当前文件以 man 格式打开(使用 WoMan)。
|
||||
Y 为所有标记的文件创建一个到指定目录的相对符号连接(即使用相对路径进行引用,而不是绝对路径)。
|
||||
|
||||
|
||||
===== *命令 =====
|
||||
** 标记所有可执行文件
|
||||
*@ 标记所有符号链接文件
|
||||
*/ 标记所有目录文件
|
||||
*s 标记所有文件为*
|
||||
*. 标记具有给定扩展名的文件
|
||||
* % REGEXP <RET>标记所有__文件名__匹配到给定的正则表达式的文件
|
||||
*s 标记__所有文件__为*
|
||||
* % REGEXP <RET>标记所有__文件名__匹配到给定的正则表达式的文件,等效的命令为%m
|
||||
*? MARKCHAR 或 M-<DEL> __去除所有以 MARKCHAR 标记的文件的标记__,如果传递一个前缀参数,则会对每一个文件要求你确认是否去除标记。
|
||||
__* c OLD-MARKCHAR NEW-MARKCHAR__ 把 * 标记变换成其他标记
|
||||
以上命令的标记为*
|
||||
*! 去除所有文件的标记,等效的命令为U
|
||||
以上命令的标记为*,它们为Dired其它命令的默认操作文件。
|
||||
|
||||
===== %命令(一般和正则表达式有关) =====
|
||||
%d REGEXP <RET> 把__文件名__符合正则表达式的文件标记为删除D
|
||||
% m REGEXP <RET> >标记所有__文件名__匹配到给定的正则表达式的文件
|
||||
% g REGEXP <RET> 标记所有__文件 内容__ 匹配到给定的正则表达式的文件
|
||||
% m REGEXP <RET> >标记所有__文件名__匹配到给定的正则表达式的文件
|
||||
% g REGEXP <RET> 标记所有__文件内容__ 匹配到给定的正则表达式的文件
|
||||
正则表达式语法为grep而非egrep
|
||||
|
||||
===== 强大的重命名功能 =====
|
||||
|
||||
dired 有一个文件名转换的理念,所以转换,并不一定是重命名,还可以是复制和创建链接。所以,除了 % u 和 % l 重命名原文件为大写、小写外,一个使用正则表达式进行转换的命令提供了四个选项: __% X 其中 X 可以是 R , C , H 和 S __,分别代表重命名、复制、创建硬链接和创建软链接,他们使用匹配和替换的机制,这有点像 rename 这个程序,例如: % R \.[^.]*$ <RET> .1\& <RET> 给原来的文件名加个标号 1 ,把 foo.txt 变成 foo.1.txt 。
|
||||
|
||||
另外,dired 还有一个叫做 __Wdired__ 的扩展可以直接在 dired 的 buffer 里面编辑文件名来达到重命名的效果。使用 __M-x wdired-change-to-wdired-mode__ 进入编辑模式,这个时候可以直接像编辑普通文本一样编辑文件名,还可以添加路径来实现把文件移动到其他目录(可以通过保存文件的方式来使更改生效)。除了文件名可以编辑以外,其他部分被标记为只读,但是如果把 __wdired-allow-to-change-permissions__ 设为 t 的话,还可以编辑文件的权限位。编辑完成之后使用 C-c C-c 来应用所做的编辑。非常方便。
|
||||
|
||||
===== 排序和过滤 =====
|
||||
|
||||
dired 有方便的排序功能,这里介绍了如何方便地使用排序功能。另外 dired 还有一个 __k__ 用于去掉不想显示出来的文件,它并不删除磁盘上的文件,只是临时从 dired 的 buffer 中去掉他们,__ g __刷新一下它们又会显示出来,这样,首先用强大的标记功能进行标记,然后使用 k 去掉,就实现了过滤的功能。
|
||||
子目录操作
|
||||
|
||||
===== 同时操作当前目录和子目录 =====
|
||||
dired 允许同时操作当前目录和子目录。在 dired-listing-switches 里面加入 R 选项就可以显示子目录,如果只是想临时显示某个子目录的内容,对该目录执行__ i __操作就会把该子目录的内容添加到 dired __当前 buffer 的末尾__并把光标移动到那里,dired 在__移动之前会先设置一个 mark__ ,所以可以使用 C-u C-<SPC> (对于我来说,我把 set-mark-command 绑定到了 M-<SPC> 上,这里自然就是使用 C-u M-<SPC> 了)回到原来的位置。
|
||||
|
||||
|
||||
还有一些方便的功能,我把几个常用的命令列在这里:
|
||||
|
||||
|
||||
|
||||
@@ -10,37 +10,11 @@ ccmx 于 2011年 一月 7日 发表 | 最后修改于 2011年 一月 10日
|
||||
|
||||
要想弄懂Autotools并使用它,必须先要了解一下M4这个怪物。那么何为M4呢,M4的名称取自Macro(M后面跟4个字母…)。它和C预处理器里的宏是一个概念(其实,M4和C预处理器都K&R操刀设计的!!),用来处理文本替换。也就是说,M4是bash里的预处理器。
|
||||
|
||||
取自维基的例子:
|
||||
divert(-1)
|
||||
This `divert' discards this text. Note that I had to quote the `divert'
|
||||
in the comment so it wouldn't get undiverted.
|
||||
This starts the count at ONE as the incr is a preincrement.
|
||||
define(`H2_COUNT', 0)
|
||||
The define H2_COUNT is redefined every time the H2 macro is used.
|
||||
The dnl deletes everything on the line after it in the output (ie this bit)
|
||||
define(`H2', `define(`H2_COUNT', incr(H2_COUNT))'dnl
|
||||
`<h2>H2_COUNT. $1</h2>')
|
||||
divert(0)dnl diversion to 0 means back to normal dnl removes this line.
|
||||
H2(First Section)
|
||||
H2(Second Section)
|
||||
H2(Conclusion)
|
||||
|
||||
这段M4宏用m4处理输出的结果就是:
|
||||
|
||||
<h2>1. First Section</h2>
|
||||
<h2>2. Second Section</h2>
|
||||
<h2>3. Conclusion</h2>
|
||||
|
||||
简单说下:
|
||||
|
||||
1.M4的语法跟C里面宏的语法差不多,都很像函数,名字加括号。
|
||||
2.M4里的参数即使声明了也是可以忽略的,如果一个宏一个参数都不加的话,括号都可以忽略。
|
||||
|
||||
懂了吧。就当你懂了。
|
||||
|
||||
autoconf就是基于M4这个工具来生成configure脚本的。
|
||||
|
||||
我们来看一个最简单的autoconf输入,将下面代码存为configure.ac:
|
||||
autoconf就是基于M4这个工具来生成configure脚本的。我们来看一个最简单的autoconf输入,将下面代码存为configure.ac:
|
||||
|
||||
AC_INIT([test], [1.0])
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
@@ -54,8 +28,6 @@ all: @PACKAGE_NAME@_bin
|
||||
gcc -o @PACKAGE_NAME@_bin test.c
|
||||
|
||||
好,下面执行命令:
|
||||
|
||||
|
||||
$ autoconf
|
||||
$ ./configure
|
||||
|
||||
@@ -67,9 +39,9 @@ test_bin: test.c
|
||||
|
||||
中间发生了什么?停我慢慢道来。
|
||||
|
||||
首先,autoconf读取configure.ac里的宏,并__调用M4处理这些宏__,做些检查,如果你很感兴趣,这些宏的实现可以在__/usr/share/autoconf/autoconf__/*.m4里找到这些宏的定义(看了不要发疯)。检查完会生成两个文件:configure。执行configure脚本生成__config.status和config.log__。config.log里面是执行的记录,config.status是下一步执行的__脚本__,用来生成Makefile,configure生成完这个脚本会自动调用的。
|
||||
首先,autoconf读取configure.ac里的宏,__并调用M4处理这些宏__,做些检查,如果你很感兴趣,这些宏的实现可以在__/usr/share/autoconf/autoconf/*.m4__里找到这些宏的定义(看了不要发疯)。检查完会生成两个文件:configure。执行configure脚本生成__config.status和config.log__。config.log里面是执行的记录,config.status是下一步执行的__脚本__,用来生成Makefile,configure生成完这个脚本会自动调用的。
|
||||
|
||||
那Makefile.in又是什么呢?那是第二个宏AC_CONFIG_FILES([Makefile])执行时的默认输入。__方括号是用来表示参数的__。就像上面的‘`’一样。Makefile.in就是一个模板,用来生成Makefile。执行configure脚本时(实际上是config.status脚本),里面的%变量%会被替换成相应的内容。有哪些变量?看看config.log就知道了。
|
||||
那Makefile.in又是什么呢?那是第二个宏AC_CONFIG_FILES([Makefile])执行时的默认输入。__方括号是用来表示参数的__。就像上面的‘`’一样。Makefile.in就是一个模板,用来生成Makefile。执行configure脚本时(实际上是config.status脚本),里面的__@变量@__会被替换成相应的内容。有哪些变量?看看config.log就知道了。
|
||||
|
||||
前面说了autotools的基本原理:将configure.ac里的宏展开,运行,生成Makefile。其实,对于大多数项目来说,configure.ac里的内容基本框架都差不多。既然都差不多那么有没有什么工具可以帮我们做这些基本的事情呢?别忘了你在linux下,有!
|
||||
|
||||
@@ -83,7 +55,6 @@ test
|
||||
└── server.c
|
||||
|
||||
在test目录下运行autoscan看看。是不是生成了如下的configure.scan呢(autoscan.log被我们无情的忽略了):
|
||||
|
||||
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
@@ -102,7 +73,7 @@ AC_PROG_CC
|
||||
**AC_CHECK_HEADERS**([netinet/in.h stdlib.h strings.h sys/socket.h unistd.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
**AC_TYPE_PID_T**
|
||||
AC_TYPE_PID_T
|
||||
|
||||
# Checks for library functions.
|
||||
AC_FUNC_FORK
|
||||
@@ -117,9 +88,7 @@ AC_CHECK_FUNCS([bzero socket])
|
||||
我们解释一下这个文件里的一些宏。
|
||||
|
||||
首先是,AC_PREREQ([2.68]),这个宏用来检查你__机器上的autoconf版本__的。这里是我机器上的版本号2.68。
|
||||
|
||||
然后AC_INIT宏,这里你要将里面的内容改改,里面的提示你懂的。我们改成下面这样:
|
||||
|
||||
AC_INIT([test], [0.1], [dccmx@test.com])
|
||||
|
||||
紧跟着是AC_CONFIG_SRCDIR([src/server.c]),__这是autoconf用来定位自己的所在目录的宏,里面的内容是所在目录下的任意一个文件就可以了__,你可以改成一个更能代表你项目的文件(这样不会更其他项目冲突),也可以不动。
|
||||
@@ -165,8 +134,6 @@ config.h.in呢?我们写一个吧,从上面autoscan生成的configure.ac来
|
||||
|
||||
看,所有存在的头文件都被define成了1,__不存在的被注释掉__。好吧,在你的程序里尽情的include吧,生活真美好。现在可以make生成可执行文件了。test_client和test_server是不是如愿生成了呢?应该是的!
|
||||
|
||||
现在我们项目中仍然有两个.in文件要我们自己写:config.h.in和Makefile.in,关于这两个文件的工具,我们后面再谈。
|
||||
|
||||
前面提到,config.h.in和Makefile.in还要手写,现在我们就来看看,Autotools里有那些工具帮助我们完成这些体力活。
|
||||
首先是config.h.in。这个非常简单,弄好configure.ac后,直接在项目根目录运行下面命令
|
||||
|
||||
@@ -174,8 +141,8 @@ __autoheader__
|
||||
|
||||
看看,是不是生成了config.h.in了,看看内容。真轻松啊,__autoheader工具分析了configure.ac里面所有要检查的东西,然后生成了相应的宏__,好了,可以用了。
|
||||
|
||||
Makefile.in的生成就比较复杂了,毕竟Makefile是个复杂的东东。
|
||||
我坦白,要自动生成Makefile.in以便让configure自动生成Makefile你必须再手动写个Makefile.am文件(这就是灵活的代价和unix的哲学)。
|
||||
Makefile.in的生成就比较复杂了,毕竟Makefile是个复杂的东东。我坦白,要自动生成Makefile.in以便让configure自动生成Makefile你必须再手动写个Makefile.am文件(这就是灵活的代价和unix的哲学)。
|
||||
|
||||
所谓Makefile.am其实就是__automake用来生成Makefile.in的模板__,里面就像一般的Makefile,只不过加了一些automake宏。
|
||||
回顾前面的目录结构,我们需要在根目录和所有源码目录添加Makefile.am文件,如下:
|
||||
|
||||
@@ -189,31 +156,25 @@ test
|
||||
└── server.c
|
||||
|
||||
先来看根目录下的Makefile.am文件:
|
||||
|
||||
SUBDIRS = src
|
||||
|
||||
灰常简单!
|
||||
再看src目录下的Makefile.am文件:
|
||||
|
||||
|
||||
bin_PROGRAMS = client server
|
||||
|
||||
client_SOURCES = client.c
|
||||
|
||||
server_SOURCES = server.c
|
||||
|
||||
同样灰常简单,这个文件,不解释,你懂的。现在应该淡定些了。
|
||||
好,现在我们还需要建一些文件AUTHORS、COPYING、NEWS、ChangeLog和README,这些文件都是gnu项目的标准文件,automake会检查这些文件的。所以,如果不想要的话先建个空文件搪塞一下吧,如果实在受不了也可以用__–foreign__参数来禁止这个检查。
|
||||
同样灰常简单,这个文件,不解释,你懂的。现在应该淡定些了。好,现在我们还需要建一些文件AUTHORS、COPYING、NEWS、ChangeLog和README,这些文件都是gnu项目的标准文件,automake会检查这些文件的。所以,如果不想要的话先建个空文件搪塞一下吧,如果实在受不了也可以用__–foreign__参数来禁止这个检查。
|
||||
|
||||
最后一步,__在configure.ac里面加上automake支持的宏__
|
||||
|
||||
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.68])
|
||||
AC_INIT([test], [1.0], [test@dccmx.com])
|
||||
AM_INIT_AUTOMAKE
|
||||
**AM_INIT_AUTOMAKE**
|
||||
AC_CONFIG_SRCDIR([src/server.c])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
@@ -233,7 +194,7 @@ AC_FUNC_FORK
|
||||
AC_FUNC_MALLOC
|
||||
AC_CHECK_FUNCS([bzero socket])
|
||||
|
||||
AC_CONFIG_FILES([Makefile src/Makefile])
|
||||
**AC_CONFIG_FILES([Makefile src/Makefile])**
|
||||
AC_OUTPUT
|
||||
|
||||
看到了,我们现在初始化部分__加了AM_INIT_AUTOMAKE 来初始化automake__,在最后又改了AC_CONFIG_FILES([Makefile src/Makefile]) ,来吧src目录下的Makefile也加入管理。
|
||||
@@ -247,19 +208,21 @@ dccmx@~/projects/console/test$ automake –a –c
|
||||
dccmx@~/projects/console/test$ make
|
||||
|
||||
神清气爽啊。在src目录里生成两个二进制文件了。make distclean看看?一切恢复如初!make dist看看,自动打包发布。生活真是美好啊。
|
||||
|
||||
等等,第一个命令是干什么的呢,这个命令是用来生成automake依赖的宏的,供autoconf调用(因为automake其实不是autoconf的一部分,只相当于插件)。automake后面的两个参数又是干什么的呢?因为automake生成的__Makefile需要一些外部脚本辅助__,而项目里是没有的,所以-a就是把这些文件__自动添加__就来,-c就是指定用__复制的方式添加__,否则是符号链接。
|
||||
|
||||
有了前面几篇文章介绍的几招,基本的构建系统就算完成了。开始离专业水平还有一定距离。我们现在看看一些后续的方法,让我们的构建脚本更加专业。
|
||||
|
||||
1.设置库依赖和预处理宏:
|
||||
|
||||
设置依赖库和宏的方法很简单,只要维护gcc的参数就ok了。这些参数在Makefile.am里面维护。
|
||||
设置依赖库和宏的方法很简单,只要维护__gcc的参数__就ok了。这些参数在**Makefile.am**里面维护。
|
||||
|
||||
先在configure.ac里面加上相关的宏:__AM_PROG_CC_C_O__。
|
||||
|
||||
要添加预处理宏的话(比如_GNU_SOURCE宏)只要在Makefile.am里面添加__xxx_CFLAGS__ = -D_GNU_SOURCE。好了。重新configure吧。
|
||||
|
||||
依赖的库呢?你猜对了,在Makefile.am里面添加__xxx_LDFLAGS__ = -lssl -lidn -lz就ok了。生活。。。真美好!
|
||||
[[autoconf---automake]]
|
||||
|
||||
2.检查目标系统上的库:
|
||||
|
||||
|
||||
@@ -5,33 +5,6 @@ Creation-Date: 2012-06-14T10:05:55+08:00
|
||||
====== GNU Automake ======
|
||||
Created Thursday 14 June 2012
|
||||
|
||||
GNU Automake
|
||||
For version 1.3, 3 April 1998
|
||||
David MacKenzie and Tom Tromey
|
||||
|
||||
@dircategory GNU admin @direntry * automake: (automake). Making Makefile.in's
|
||||
@dircategory Individual utilities @direntry * aclocal: (automake)Invoking aclocal. Generating aclocal.m4
|
||||
Copyright (C) 1995, 96 Free Software Foundation, Inc.
|
||||
|
||||
这是GNU Automake文档的第一版,
|
||||
并且是针对GNU Automake 1.3的。
|
||||
|
||||
自由软件基金会出版
|
||||
59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.
|
||||
|
||||
只要版权声明和本许可声明保留在所有副本中,您就被授权制作和发行本手册的 原文副本。
|
||||
只要整个最终派生工作按照与本手册相同的许可声明发行,您就被授权按照与 发行原文相同的条件复制和发行本手册的修改版本。
|
||||
除了本许可声明应该使用由基金会批准的译文之外,您被授权按照与上述修改 版本相同的条件复制和发行本手册的其它语言的译文。
|
||||
本文档由王立翻译。 1999.12.17
|
||||
译者在此声明:不对任何由译文错误或者对译文的误解承担任何责任。
|
||||
|
||||
===== 介绍 =====
|
||||
|
||||
__Automake是一个从文件`Makefile.am'自动生成`Makefile.in' 的工具__。每个`Makefile.am'基本上是__一系列make的宏定义__ (make规则也会偶尔出现)。生成的`Makefile.in's服从GNU Makefile标准。
|
||||
@@ -60,13 +33,14 @@ Automake不能识别GNU对make的扩展。在`Makefile.am'中使用这些扩展
|
||||
|
||||
Automake试图明智地把注释和相邻的目标(或者变量定义)关联起来。
|
||||
|
||||
在`Makefile.am'中定义的目标通常覆盖了所有由automake 自动生成的拥有相似名字的目标。虽然Automake提供了这一功能,但最好避免使用它, 因为有些时候生成的规则将是十分特别的。
|
||||
在`Makefile.am'中定义的目标通常__覆盖了__所有由automake 自动生成的拥有相似名字的目标。虽然Automake提供了这一功能,但最好避免使用它, 因为有些时候生成的规则将是十分特别的。
|
||||
|
||||
类似地,__在`Makefile.am'中定义的变量将覆盖任何通常由automake 创建的变量定义__。该功能比覆盖目标定义的功能要常用得多。需要警告的是许多由 automake生成的变量都被认为是内部使用的,并且它们的名字可能在未来 的版本中改变。
|
||||
类似地,__在`Makefile.am'中定义的变量将覆盖任何通常由automake 创建的变量定义__。该功能比覆盖目标定义的功能要常用得多。需要警告的是许多由 automake生成的变量都被认为是内部使用的,并且它们的名字可能在未来的版本中改变。
|
||||
|
||||
在检验变量定义的时候,Automake将递归地检验定义中的变量引用。例如,如果Automake 在如下片断中搜索`foo_SOURCES'的内容。
|
||||
|
||||
xs = a.c b.c foo_SOURCES = c.c $(xs)
|
||||
xs = a.c b.c
|
||||
foo_SOURCES = c.c $(xs)
|
||||
|
||||
它将把文件`a.c'、 `b.c'和 `c.c'作为`foo_SOURCES' 的内容。
|
||||
|
||||
@@ -80,7 +54,7 @@ Automake还允许给出不被复制到输出中的注释;所有以`##'开头
|
||||
|
||||
automake支持三种目录层次: “flat”、“shallow”和“deep”。
|
||||
|
||||
* 一个flat(平)包指的是__所有文件__都在一个目录中的包。为这类包提供的`Makefile.am' 缺少宏SUBDIRS。这类包的一个例子是termutils。
|
||||
* 一个flat(平)包指的是__所有文件__都在一个目录中的包。为这类包提供的`Makefile.am' 缺少__宏SUBDIRS__。这类包的一个例子是termutils。
|
||||
* 一个deep(深)包指的是所有的源代码都被储存在子目录中的包;顶层目录主要包含配置信息。GNU cpio 是这类包的一个很好的例子,GNU tar也是。deep包的顶层`Makefile.am'将包括宏SUBDIRS,但没有定义需要创建的对象的宏(**所有的对象如可执行程序和库文件都是在SUBDIRS中的makefle.am中定义的**)。
|
||||
* 一个shallow(浅)包指的是主要的源代码储存在顶层目录中,而各个部分(典型的是库)则储存在子目录中的包。Automake本身就是这类包(GNU make也是如此,它现在已经不使用automake)。这样顶层的makefile.am既包括SUBDIRS宏,__也包括__创建对象的宏定义(使用的是顶层目录的源代码)。
|
||||
|
||||
@@ -115,7 +89,7 @@ EXTRA_PROGRAMS = mt rmt
|
||||
bin_PROGRAMS = cpio pax
|
||||
sbin_PROGRAMS = @PROGRAMS@
|
||||
|
||||
定义没有前缀的主变量(比如说PROGRAMS)是错误的。
|
||||
定义没有__前缀__的主变量(比如说PROGRAMS)是错误的。
|
||||
|
||||
在构造变量名的时候,通常省略后缀`dir';因此我们使用 `bin_PROGRAMS'而不是`bindir_PROGRAMS'.
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ Created Thursday 14 June 2012
|
||||
http://railsmonkey.net/2010/05/is-your-build-environment-sane/
|
||||
|
||||
Is your build environment ‘sane’…?
|
||||
|
||||
By Matthew Savage
|
||||
|
||||
I’ve been testing a Varnish reverse-proxy/cache setup this weekend to try to resolve the ’80%’ of the problems I’ve been dealing with across our websites.
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-06-14T10:36:42+08:00
|
||||
|
||||
====== 图解autoscan、aclocal、autoheader、automake、autoconf、configure、make ======
|
||||
Created Thursday 14 June 2012
|
||||
http://hi.baidu.com/yzkuang/blog/item/557e4f24423d8136c9955908.html
|
||||
|
||||
1.autoscan (autoconf): 扫描源代码以搜寻普通的__可移植性问题__,比如检查编译器,库,头文件等,生成文件configure.scan,它是configure.ac的一个雏形。
|
||||
|
||||
your source files --> [autoscan*] --> [configure.scan] --> configure.ac
|
||||
|
||||
2.aclocal (automake):根据已经安装的宏,用户定义宏和__acinclude.m4__文件中的宏将configure.ac文件所需要的宏集中定义到文件 aclocal.m4中。aclocal是一个perl 脚本程序,它的定义是:“aclocal - create aclocal.m4 by scanning configure.ac”
|
||||
|
||||
user input files optional input process output files
|
||||
================ ============== ======= ============
|
||||
|
||||
acinclude.m4 - - - - -.
|
||||
V
|
||||
.-------,
|
||||
configure.ac ------------------------>|aclocal|
|
||||
{user macro files} ->| |------> aclocal.m4
|
||||
`-------'
|
||||
3.autoheader(autoconf): 根据configure.ac中的某些宏,比如cpp宏定义,运行m4,生成config.h.in
|
||||
|
||||
user input files optional input process output files
|
||||
================ ============== ======= ============
|
||||
|
||||
aclocal.m4 - - - - - - - .
|
||||
|
|
||||
V
|
||||
.----------,
|
||||
configure.ac ----------------------->|autoheader|----> autoconfig.h.in
|
||||
`----------'
|
||||
|
||||
4.automake: automake将Makefile.am中定义的结构建立Makefile.in,然后configure脚本将生成的Makefile.in文件转换为Makefile。如果在configure.ac中定义了一些特殊的宏,比如__AC_PROG_LIBTOOL__,它会调用__libtoolize__,否则它会自己产生config.guess和config.sub
|
||||
|
||||
user input files optional input processes output files
|
||||
================ ============== ========= ============
|
||||
|
||||
.--------,
|
||||
| | - - -> COPYING
|
||||
| | - - -> INSTALL
|
||||
| |------> install-sh
|
||||
| |------> missing
|
||||
|automake|------> mkinstalldirs
|
||||
configure.ac ----------------------->| |
|
||||
Makefile.am ----------------------->| |------> Makefile.in
|
||||
| |------> stamp-h.in
|
||||
.---+ | - - -> config.guess
|
||||
| | | - - -> config.sub
|
||||
| `------+-'
|
||||
| | - - - -> config.guess
|
||||
|libtoolize| - - - -> config.sub
|
||||
| |--------> ltmain.sh
|
||||
| |--------> ltconfig
|
||||
`----------'
|
||||
|
||||
The `libtoolize' program __provides a standard way to add libtool support to your package__. In the future, it may implement better usage
|
||||
checking, or other features to make libtool even easier to use.
|
||||
|
||||
5.autoconf:将configure.ac中的宏展开,生成configure脚本。这个过程可能要用到aclocal.m4中定义的宏。
|
||||
|
||||
user input files optional input processes output files
|
||||
================ ============== ========= ============
|
||||
|
||||
aclocal.m4 ,autoconfig.h.in - - - - - - -.
|
||||
V
|
||||
.--------,
|
||||
configure.ac ----------------------->|autoconf|------> configure
|
||||
|
||||
|
||||
|
||||
6. ./configure的过程
|
||||
|
||||
|
||||
.-------------> [config.cache]
|
||||
configure* --------------------------+-------------> config.log
|
||||
|
|
||||
[config.h.in] -. v .--> [autoconfig.h]
|
||||
+-------> config.status* -+
|
||||
Makefile.in ---' `--> Makefile
|
||||
|
||||
|
||||
|
||||
7. make过程
|
||||
|
||||
|
||||
|
||||
[autoconfig.h] -.
|
||||
+--> make* ---> 程序
|
||||
Makefile ---'
|
||||
|
||||
|
||||
|
||||
.---------,
|
||||
config.site - - ->| |
|
||||
config.cache - - ->| | - - -> config.cache
|
||||
| +-,
|
||||
`-+-------' |
|
||||
| |----> config.status
|
||||
config.h.in ------->|config- |----> config.h
|
||||
Makefile.in ------->| .status|----> Makefile
|
||||
| |----> stamp-h
|
||||
| +--,
|
||||
.-+ | |
|
||||
| `------+--' |
|
||||
ltmain.sh ------->|ltconfig|-------> libtool
|
||||
| | |
|
||||
`-+------' |
|
||||
|config.guess|
|
||||
| config.sub |
|
||||
`------------'
|
||||
|
||||
.--------,
|
||||
Makefile ------>| |
|
||||
config.h ------>| |
|
||||
{project sources} ---------------->| |--------> {project targets}
|
||||
.-+ +--,
|
||||
| `--------' |
|
||||
| libtool |
|
||||
| missing |
|
||||
| install-sh |
|
||||
|mkinstalldirs|
|
||||
`-------------'
|
||||
@@ -1,40 +0,0 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-06-14T09:19:47+08:00
|
||||
|
||||
====== automake变量 ======
|
||||
Created Thursday 14 June 2012
|
||||
http://www.delorie.com/gnu/docs/automake/automake_47.html
|
||||
|
||||
**9.6 Variables used when building a program**
|
||||
|
||||
Occasionally it is useful to know which `Makefile' variables Automake uses for compilations; for instance you might need to do your own compilation in some special cases.
|
||||
|
||||
Some variables are **inherited**// from Autoconf//; these are __CC, CFLAGS, CPPFLAGS, DEFS, LDFLAGS, and LIBS__.
|
||||
|
||||
There are some additional variables which Automake **itself** defines:
|
||||
|
||||
* **AM_CPPFLAGS**
|
||||
The contents of this variable are passed to **every compilation** which invokes the C preprocessor; it is a list of arguments to the preprocessor. For instance, `-I' and `-D' options should be listed here.
|
||||
|
||||
Automake already provides some `-I' options automatically. In particular it generates __`-I$(srcdir)', `-I.'__, and a `-I' pointing to the directory holding `config.h' (if you've used AC_CONFIG_HEADERS or AM_CONFIG_HEADER). You can disable the default `-I' options using the `nostdinc' option.
|
||||
|
||||
AM_CPPFLAGS is ignored in preference to a __per-executable (or per-library) _CPPFLAGS variable__ if it is defined.
|
||||
|
||||
* AM_CPPFLAGS是一个全局变量,会传给每一个编译预处理命令。
|
||||
* 我们也可以通过filename_CPPFLAGS的形式为每一个可执行程序或库文件指定编译预处理选项。当定义这个变量时AM_CPPFLAGS会被忽略。
|
||||
|
||||
* **INCLUDES** (将被弃用的变量)
|
||||
This does the same job as `AM_CPPFLAGS'. It is an older name for the same functionality. This variable is __deprecated;__ we suggest using `AM_CPPFLAGS' instead.
|
||||
|
||||
* **AM_CFLAGS**
|
||||
This is the variable which the `Makefile.am' author can use to pass in **additional C compiler flags**. It is more fully documented elsewhere. In some situations, this is not used, in preference to the __per-executable (or per-library) _CFLAGS__.
|
||||
|
||||
* **COMPILE**
|
||||
This is the command used to actually compile a C source file. The filename is appended to form the complete command line.
|
||||
|
||||
* **AM_LDFLAGS**
|
||||
This is the variable which the `Makefile.am' author can use to pass in **additional linker flags**. In some situations, this is not used, in preference to the __per-executable (or per-library) _LDFLAGS__.
|
||||
|
||||
* **LINK**
|
||||
This is the command used to actually link a C program. It already includes `-o $@' and the usual variable references (for instance, CFLAGS); it takes as "arguments" the names of the object files and libraries to link in.
|
||||
@@ -33,10 +33,6 @@ Other formats
|
||||
|
||||
The widespread use of these configure scripts made building software from the sources easier. This document discusses the software packages used to generate the configure script and other associated files.
|
||||
|
||||
This document is aimed at developers intending to develop Free Software or already maintaining Free Software packages.
|
||||
|
||||
We assume the reader is already familiar with Makefiles.
|
||||
|
||||
===== 2. Who's who =====
|
||||
|
||||
The software packages we are dealing directly with here are: **GNU autoconf, GNU automake and GNU autoheader**. Indirectly, we are dealing with the **m4** macro processor, **make** (either GNU or BSD),**aclocal **and **libtool**. We talk about GNU libtool too.
|
||||
@@ -154,7 +150,7 @@ You should see an output like this
|
||||
galadriel:~/autotut-ex1$
|
||||
|
||||
|
||||
* configure.in是autoconf的输入文件,autoconf展开其中的宏引用,然后输出到configure脚本文件中。
|
||||
* configure.in是autoconf的输入文件,autoconf展开其中的宏引用,然后输出到configure脚本文件中,同时它也是个bash脚本。
|
||||
* configure.in中引用的宏定义一般是由aclocal扫描该文件后从系统宏库中提取出来,然后写入到源代码目录中的aclocal.m4文件中的。
|
||||
* makefile.in是configure脚本的输入文件,configure脚本根据__配置参数和系统环境检查结果替换__makefile.in文件中包含在两@间的变量,然后输出到makefile文件中。
|
||||
* configure脚本检查哪些项目(头文件、库文件及其中函数等),读取和替换哪些makefile.in等是由configure.in中的各种宏决定的。
|
||||
@@ -169,9 +165,10 @@ You should see an output like this
|
||||
|
||||
The configure.in file is processed by the __m4 macro processor__, but aside from the m4 macros, __it is a Bourne shell script__. Thus you can use if...then...fi, and constructs from Bourne shells. You can have some reference on shell programming by reading the bash or sh man pages (depending on the operating system you are on).
|
||||
|
||||
IMPORTANT! The square brackets have special meaning to the m4 processor, so if you want to use the test (see test (1)) command you must spell it out as **test** instead of using the Bourne shell [...] abbreviation.
|
||||
IMPORTANT! The __square brackets__ have special meaning to the m4 processor, so if you want to use the test (see test (1)) command you must spell it out as **test** instead of using the Bourne shell [...] abbreviation.
|
||||
|
||||
configure.in是一个文本文件,它__会被M4宏处理器和shell读取执行__,因此其中可以包含M4能够识别并展看的__以AC_或AM_开头的宏函数__,也可以包含shell脚本语法内容。
|
||||
|
||||
注意:configure.in中的__方括号对于M4而言有特殊含义__,因此不在具有shell脚本中的测试功能,如果要使用shell的判断功能,可以使用test命令。
|
||||
|
||||
Also, **the shell variables** defined and modified within configure.in are NOT substituted automatically in the AC_OUTPUT files. You must explicitly call __AC_SUBST__ (as done with the VERSION variable in the first example) to request the substitution. However, when an internal autoconf macro says "sets variable NAME", it sets and AC_SUBSTs it, thus you must only worry about variables set on your own.
|
||||
@@ -188,7 +185,8 @@ configure.in是一个文本文件,它__会被M4宏处理器和shell读取执
|
||||
this is parameter 3 which spans
|
||||
along several lines. Now you
|
||||
know why square brackets cannot
|
||||
be used for the 'test' command.]) //M4宏的参数//如果以方括号开头,则可以分布在多个行中//。
|
||||
be used for the 'test' command.])
|
||||
//M4宏的参数//如果以方括号开头,则可以分布在多个行中。
|
||||
|
||||
Conventionally , all macros provided by //autoconf// start with __AC___. As we shall see later, //automake//'s macros start with __AM___.
|
||||
|
||||
@@ -198,15 +196,15 @@ configure.in是一个文本文件,它__会被M4宏处理器和shell读取执
|
||||
|
||||
**Macro Prototype Comments**
|
||||
AC_INIT(sourcefile) Initializes autoconf, should be __the first macro__ called in configure.in(第一个宏函数调用,但是在其前面**可以有变量定义**。). sourcefile is the name (relative to //current// directory) of a source file from your code.
|
||||
AC_PROG_CC Determines a C compiler to use, sets the __CC__ variable. If this is GCC, set the __GCC__ variable to 'yes', otherwise 'no'. Initializes the __CFLAGS__ variable if it hasn't been set already (to override CFLAGS, do it in configure.in __BEFORE__ calling this macro) 如果CFLAGS变量没有定义,则该宏会初始化它为默认值。CLFAGS的定义可以来自本文将,也可来自命令行参数。
|
||||
AC_PROG_CXX Determines a C++ compiler to use, sets the __CXX__ variable. If this is the GNU C++ compiler, set __GXX__ to 'yes', otherwise 'no'. Initializes the __CXXFLAGS__ variable if it hasn't been set already (to override CXXFLAGS, do it in configure.in BEFORE calling this macro)
|
||||
AC_PROG_CC Determines a C compiler to use, sets the __CC__ variable. If this is GCC, set the __GCC__ variable to 'yes', otherwise 'no'. Initializes the __CFLAGS__ variable if it hasn't been set already (to override CFLAGS, do it in configure.ac __BEFORE__ calling this macro) 如果CFLAGS变量没有定义,则该宏会初始化它为默认值。CLFAGS的定义可以来自本文件,也可来自命令行参数。
|
||||
AC_PROG_CXX Determines a C++ compiler to use, sets the __CXX__ variable. If this is the GNU C++ compiler, set __GXX__ to 'yes', otherwise 'no'. Initializes the __CXXFLAGS__ variable if it hasn't been set already (to override CXXFLAGS, do it in configure.ac BEFORE calling this macro)
|
||||
AC_LANG_C Tests the C compiler //**测试C编译器能否正常工作**
|
||||
AC_LANG_CPLUSPLUS Tests the C++ compiler
|
||||
AC_PROG_INSTALL Set variable __INSTALL__ to the path of a BSD-compatible //install program// (see install (1)). If not found, set it to 'dir/install-sh -c' , looking in the directories specified to __AC_CONFIG_AUX_DIR__. Also sets __INSTALL_SCRIPT__ and __INSTALL_PROGRAM__ to $(INSTALL), and __INSTALL_DATA__ to '$(INSTALL) -m 644'. You must provide __a install-sh file__ in the current directory (unless you use AC_CONFIG_AUX_DIR -- the common practice is to provide a install-sh file) else autoconf will refuse to run. //install-sh为安装该程序的系统提供一个**install程序的候选版本**。
|
||||
AC_PATH_X Try to locate the **X window system**'s includes and libraries, and sets the variables __x_includes__ and __x_libraries__ to their locations.
|
||||
AC_PATH_XTRA Like the previous, but adds the required include flags to __X_CFLAGS__ and required linking flags to __X_LIBS__.
|
||||
|
||||
AC_PATH_PROG(a,b[,c[,d]])
|
||||
AC_PATH_PROG(a,b[,c[,d]]) //在系统路径PATH中查找prog-to-check程序是否存在
|
||||
a=variable-name
|
||||
b=prog-to-check
|
||||
c=value-if-not-found
|
||||
@@ -214,23 +212,23 @@ configure.in是一个文本文件,它__会被M4宏处理器和shell读取执
|
||||
|
||||
AC_PROG_MAKE_SET If make predefines the variable MAKE, define output variable __SET_MAKE__ to be empty. Otherwise, define SET_MAKE to contain `MAKE=make'. 如果是多级编译,则MAKE环境变量必须要检查。
|
||||
|
||||
AC_OUTPUT(files [,a[,b]]) Create output files. __Perform substitutions on files__, which contains a list of files separated by **spaces**. (is writes, say, Makefile, from a Makefile__.in__ file, spec from spec__.in__, and so on. **The name given here is without the .in suffix.** The other 2 parameters are seldom used, consult the autoconf docs if needed. If AC_CONFIG_HEADER, AC_LINK_FILES or AC_CONFIG_SUBDIRS were called, the files named as their arguments are created too.
|
||||
AC_OUTPUT(files [,a[,b]]) Create output files. __Perform substitutions on files__, which contains a list of files separated by **spaces**. (is writes, say, Makefile, from a Makefile__.in__ file, spec from spec__.in__, and so on. **The name given here is without the .in suffix.** The other 2 parameters are seldom used, consult the autoconf docs if needed. If __AC_CONFIG_HEADER__, __AC_LINK_FILES__ or __AC_CONFIG_SUBDIRS__ were called, the files named as their arguments are created too.
|
||||
|
||||
该宏一般位于configure.in的最后,指明了替换其中的变量引用后生成的文件filename(可能带路径),同时也指出了需要替换的模板文件filename.in,读入和输出都是由//将要生成的configure脚本//完成。
|
||||
|
||||
AC_CONFIG_HEADER(files) Make AC_OUTPUT create the headers listed in the files list (space-separated). Replaces @DEFS@ in generated files with -DHAVE_CONFIG_H. The usual name for the header is **config.h** (created from **config.h.in**. The __autoheader__ generates config.h.in files automatically for you (it is documented in the next sections).
|
||||
AC_CONFIG_HEADER(files) Make AC_OUTPUT create the headers listed in the **files list **(space-separated, 外侧不需要加方括号). Replaces @DEFS@ in generated files with -DHAVE_CONFIG_H. The usual name for the header is **config.h** (created from **config.h.in**. The __autoheader__ generates config.h.in files automatically for you (it is documented in the next sections).
|
||||
|
||||
AC_CONFIG_SUBDIRS(dirs) run configure scripts in the subdirectories listed in dirs (space-separated). This is meant for when you __nest child packages__ to your program (like including libraries as subdirs). 该宏适用于nest类型的源代码目录结构,dirs中的各目录**含有configure.in文件**。
|
||||
**AC_CONFIG_SUBDIRS(dirs)** **run configure scripts** in the subdirectories listed in dirs (space-separated). This is meant for when you __nest child packages__ to your program (like including libraries as subdirs). 该宏适用于nest类型的源代码目录结构,dirs中的各目录**含有configure.in文件**。
|
||||
|
||||
AC_CHECK_FUNC(a[,b[,c]])
|
||||
a=function
|
||||
b=action if found
|
||||
c=action if not found checks if the given C function is available in the standard library (i.e., the libraries that are linked by default to any C program).
|
||||
c=action if not found checks if the given C function is available in the __standard library__ (i.e., the libraries that are linked by default to any C program).
|
||||
|
||||
AC_CHECK_FUNCS(a[,b[,c]])
|
||||
a=list of functions (space-separated)
|
||||
b=action if found
|
||||
c=action if not found similar to AC_CHECK_FUNC, but looks for many functions at once, setting HAVE_function for each function found (in the given set).
|
||||
c=action if not found similar to AC_CHECK_FUNC, but looks for many functions at once, setting **HAVE_function** for each function found (in the given set).
|
||||
|
||||
AC_CHECK_LIB(a,b[,c[,d[,e]]])
|
||||
a=library name
|
||||
@@ -258,7 +256,8 @@ configure.in是一个文本文件,它__会被M4宏处理器和shell读取执
|
||||
There are many more autoconf macros. If these weren't already enough, you can supply **a macro library** with your own software distribution. To do this, place the macro definitions in a file called __aclocal.m4__ in the same directory as configure.in, all macros defined in aclocal can now be used in configure.in. The common use for this is to have **specific-library checking macros**, e.g. AC_REQUIRE_GTK(1,2,8) to require the GTK library version 1.2.8 or later. You may also place your macros in a file called __acinclude.m4__ if you are using the __aclocal__ program. aclocal will be presented later.
|
||||
|
||||
上面列出的以AC_开头的宏都是autoconf工具提供的标准宏,可以直接调用。程序员也可以将自己定义的宏放在aclocal.m4或acinclude.m4文件中,这样configure.in中就可以使用它们。
|
||||
注意:没当运行aclocal命令后,aclocal.m4文件中的内容就会被覆盖为代码中使用的宏定义,这样安装这个代码的系统如果没有安装这些宏也可以正常使用autoconf工具重新生成configure脚本,configure脚本运行时就不在需要autoconf,automake,autoheader和aclocal等工具。程序员将自己定义的宏放在acinclude.m4文件中就可以避免被覆盖,该文件会被acloacl自动读取。
|
||||
|
||||
注意:每当运行aclocal命令后,aclocal.m4文件中的内容就会被覆盖为代码中使用的宏定义,这样安装这个代码的系统如果没有安装这些宏也可以正常使用autoconf工具重新生成configure脚本,configure脚本运行时就不在需要autoconf,automake,autoheader和aclocal等工具。程序员将自己定义的宏放在acinclude.m4文件中就可以避免被覆盖,该文件会被acloacl自动读取。
|
||||
|
||||
And don't be tempted to have configure.in for each directory in your source tree. Multiple configure.in's are only desirable when you integrate different software packages in a common source tree (such as my program and the 3000 libraries it requires).
|
||||
|
||||
@@ -281,6 +280,15 @@ configure.in是一个文本文件,它__会被M4宏处理器和shell读取执
|
||||
|
||||
__The solution is to put all the definitions in a header file.__ You can do that in autoconf with the __AC_CONFIG_HEADER__ macro. The conventional name for this header is __config.h__. However, you must supply a __.in header__ (config.h.in) with all the possible definitions spelled out, so that autoconf will just change #undef to #define or add a value to the #define. Here comes autoheader. Just run **autoheader** on a directory with a configure.in that contains a AC_CONFIG_HEADER macro call, and it will write the __.in file__.
|
||||
|
||||
当程序员在编写程序时,可能需要一些特性或变量,而且这些特性和变量是程序的最终用户__在运行configure脚本时才配置或指定的__。
|
||||
为了利用这些变量或开关特性,程序员通常的做法是在代码中定义一些宏变量以及条件编译语句,然后用户在编译时的__gcc命令行__上用-DMarco-name=value的形式为这些宏赋值。把宏定义及其值在gcc的命令行上指定的最大缺点是:
|
||||
1. gcc命令行过长,可读性降低。
|
||||
2. 相同的宏需要在使用的每个gcc命令行上指定,非常繁琐。
|
||||
|
||||
解决的方法是将相关的宏定义放在一个众所周知的头文件中(如config.h),然后使用这些宏的代码文件只需include该头文件即可。
|
||||
config.h来源于一个模板文件config.h.in,默认其中的各宏都是#undef的,用户在执行的configure脚本在收集到相关系统和配置信息
|
||||
后会替换config.h.in中的相关宏定义,然后将结果写入到config.h中。
|
||||
|
||||
Let's use the same pi.c program we did before to show the work of autoheader. You can get the files in a tarball too: autotut-ex2.tar.gz. I won't list all files again, just configure.in.
|
||||
|
||||
**Example 2: configure.in**
|
||||
@@ -295,7 +303,7 @@ configure.in是一个文本文件,它__会被M4宏处理器和shell读取执
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_FUNCS(atol atoi strtod)
|
||||
AC_CHECK_FUNCS(atol atoi strtod) //从标准C库中检查是否穿在这些函数
|
||||
|
||||
VERSION="0.0.1-rc2"
|
||||
AC_SUBST(VERSION)
|
||||
@@ -323,7 +331,7 @@ configure.in是一个文本文件,它__会被M4宏处理器和shell读取执
|
||||
/* Define if you have the strtod function. */
|
||||
#undef HAVE_STRTOD
|
||||
|
||||
And now you run configure as usual. It will write a config.h based on this template. Let's see what it generates:
|
||||
And now you run //configure// as usual. It will write a config.h based on this template. Let's see what it generates:
|
||||
|
||||
**Example 2: config.h**
|
||||
|
||||
@@ -347,7 +355,8 @@ configure.in是一个文本文件,它__会被M4宏处理器和shell读取执
|
||||
Also, autoheader only copies definitions from the /usr/share/autoconf/acconfig.h file. If some macro you used needs a different entry in config.h.in, write it in a file called **acconfig.h** in the same directory as configure.in, and it will be included in config.h.in by autoheader.
|
||||
|
||||
autoheader工具分析了configure.ac里面所有要检查的东西,然后生成了相应的编译预处理宏定义到config.h.in文件中,然后configure脚本根据检测到的结果修改该文件并输出到config.h文件中。
|
||||
程序代码可以包含该config.h文件,根据其中的宏定义条件包含一些代码。
|
||||
|
||||
程序代码应该包含该config.h文件,可以引用其中的宏定义只进行条件编译。
|
||||
|
||||
===== 6. Automake =====
|
||||
|
||||
@@ -381,7 +390,7 @@ autoheader工具分析了configure.ac里面所有要检查的东西,然后生
|
||||
|
||||
In the next sections we present __GNU automake, which generates a Makefile.in file based on a Makefile.am file__.
|
||||
|
||||
Makefile.am只是定义一些automake可以识别的并且会包含到生成的makefile文件中的__变量,automake工具会根据这些变量自动创建相关编译规则,然后写入到makefile.in文件中,__而且auomake还会向最终生成的Makefile.in文件中添加一些标准目标规则。configure脚本会更改Makefile.in中的变量引用。
|
||||
Makefile.am只是定义一些automake可以识别的并且会包含到生成的makefile文件中的__变量,automake工具会根据这些变量自动创建相关编译规则,然后写入到makefile.in文件中,__而且auomake还会向最终生成的Makefile.in文件中添加一些标准目标规则。configure脚本会更改Makefile.in中的变量引用。 makefile.in与makefile的唯一区别就是其中的@xxx@变量被configure脚本替换为实际值(可以通过config.log文件查看这些变量值)。
|
||||
|
||||
Automake will also look for missing files that may cause your users to be confused if they are not present. Automake will either place a standard one in the package directory or complain about the missing file. (The rule is that universal files are copied from automake's distribution, and package-dependent files like AUTHORS, ChangeLog, etc. aren't).
|
||||
|
||||
@@ -402,10 +411,8 @@ Makefile.am中定义的只是一些符合makefile语法的__变量__。
|
||||
|
||||
===== Create an empty directory for the project =====
|
||||
|
||||
|
||||
mkdir gdu
|
||||
|
||||
|
||||
===== Place source files =====
|
||||
|
||||
For gdu, the source is consists of 2 C++ source files (.cc), 1 C++ header (.h), 6 pixmap pictures for the toolbar (.xpm) and a man page for the program (gdu.1x).
|
||||
@@ -419,7 +426,9 @@ Makefile.am中定义的只是一些符合makefile语法的__变量__。
|
||||
|
||||
===== 3. Write configure.in(该文件同时被autoconf和autoheader检查) =====
|
||||
|
||||
Write a configure.in file for autoconf. Notice that some automake macros (AM_) come in, and **some autoconf macros are replaced by automake macros**. You must call AM_INIT_AUTOMAKE(package,version) right after AC_INIT, use AM_CONFIG_HEADER instead of AC_CONFIG_HEADER.
|
||||
Write a configure.in file for autoconf. Notice that some automake macros (AM_) come in, and **some autoconf macros are replaced by automake macros**. 这意味着在运行automake前必须要准备好configure.in文件。
|
||||
|
||||
You must call AM_INIT_AUTOMAKE(package,version) right after AC_INIT, use AM_CONFIG_HEADER instead of AC_CONFIG_HEADER.
|
||||
|
||||
This is our configure.in:
|
||||
|
||||
@@ -429,7 +438,7 @@ Makefile.am中定义的只是一些符合makefile语法的__变量__。
|
||||
__AM_INIT_AUTOMAKE(__gdu,0.0.1) //由于使用了AM_宏,因此该宏必须放在AC_INIT宏的后面。
|
||||
__AM_CONFIG_HEADER__(config.h)
|
||||
|
||||
CXXFLAGS=
|
||||
CXXFLAGS= //这里定义了CXXFLAGS变量,会覆盖autoconf自动产生的值。
|
||||
|
||||
AC_PROG_CC # for AM_PROG_GTK only
|
||||
AC_PROG_CXX
|
||||
@@ -440,7 +449,7 @@ Makefile.am中定义的只是一些符合makefile语法的__变量__。
|
||||
|
||||
# it will define GTK_CFLAGS and GTK_LIBS for us,
|
||||
# comes from gtk.m4 (aclocal will find it for us)
|
||||
AM_PATH_GTK(1.2.6)
|
||||
AM_PATH_GTK(1.2.6) //系统预定义宏
|
||||
|
||||
AC_LANG_CPLUSPLUS # else AM_PATH_GTK blows up
|
||||
|
||||
@@ -452,21 +461,20 @@ Makefile.am中定义的只是一些符合makefile语法的__变量__。
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
|
||||
If you use macros from system aclocal files (usually in /usr/share/aclocal), as we did here (the AM_PROG_GTK macro is in /usr/share/aclocal/gtk.m4, and some automake macros must be imported too), you must run the **aclocal** program to create an __aclocal.m4__ file with all needed macros. This file is overwritten every time aclocal is run, so if you want to have your own macros written locally, place them in __acinclude.m4__, aclocal will include these in the generated aclocal.m4.
|
||||
If you use macros from system aclocal files (usually in /usr/share/aclocal), as we did here (the AM_PROG_GTK macro is in /usr/share/aclocal/gtk.m4, and some automake macros must be imported too), you must run the **aclocal** program to create an __aclocal.m4__ file with all needed macros. This file is __overwritten__ every time aclocal is run, so if you want to have your own macros written locally, place them in __acinclude.m4__, aclocal will include these in the generated aclocal.m4.
|
||||
|
||||
|
||||
===== Run aclocal, autoconf, autoheader =====
|
||||
|
||||
|
||||
Now you can already generate some of the files. You must run aclocal, autoheader and autoconf; **aclocal must run first**. In a Bourne shell you can run all three in a row with
|
||||
Now you can already generate some of the files. You must run aclocal, autoheader and autoconf; **aclocal **__must run first__. In a Bourne shell you can run all three in a row with
|
||||
|
||||
//aclocal && autoheader && autoconf//
|
||||
|
||||
* aclocal will generate an aclocal.m4 file (getting information from **configure.in** [needed] and **acinclude.m4** [optional]).
|
||||
* autoheader will read **configure.in** and produce a __config.h.in__ file (or whatever you named it in the AM_CONFIG_HEADER macro).
|
||||
* autoconf will read **configure.in** and **aclocal.m4** and produce a __configure__ script.
|
||||
* autoconf需要利用aclocal.m4中的宏定义来展开configure.in中的宏函数调用,这个过程中需要调用系统的M4工具。但是一旦生成了configure脚本,aclocal.m4和M4工具不在是必需的了(除非
|
||||
用户在配置前修改了configure.in中的宏调用,这样需要重新调用autoconf工具生成cofigure脚本)。
|
||||
|
||||
autoconf需要利用aclocal.m4中的宏定义来展开configure.in中的宏函数调用,这个过程中需要调用系统的M4工具。但是一旦生成了configure脚本,aclocal.m4和M4工具不在是必需的了(除非用户在配置前修改了configure.in中的宏调用,这样需要重新调用autoconf工具生成cofigure脚本)。
|
||||
|
||||
|
||||
===== Write a Makefile.am =====
|
||||
@@ -475,7 +483,7 @@ Makefile.am中定义的只是一些符合makefile语法的__变量__。
|
||||
|
||||
**GDU (Example 3): Makefile.am**
|
||||
|
||||
AUTOMAKE_OPTIONS = __gnu__
|
||||
AUTOMAKE_OPTIONS = gnu
|
||||
LDADD = @GTK_LIBS@
|
||||
CPPFLAGS = @GTK_CFLAGS@ //这两个变量是由configure.in中的AM_PATH_GTK(1.2.6)宏引入。
|
||||
bin_PROGRAMS = gdu //生成一个可执行文件gdu
|
||||
@@ -486,7 +494,7 @@ Makefile.am中定义的只是一些符合makefile语法的__变量__。
|
||||
# man page
|
||||
man_MANS = gdu.1x
|
||||
|
||||
# we want these **in the dist tarball**
|
||||
# we want these in the dist tarball
|
||||
EXTRA_DIST = back.xpm reload.xpm root.xpm \
|
||||
home.xpm stop.xpm about.xpm gdu.1x
|
||||
|
||||
@@ -494,7 +502,7 @@ Makefile.am中定义的只是一些符合makefile语法的__变量__。
|
||||
|
||||
AUTOMAKE_OPTIONS = gnu could be achieved by running //automake// with the __--gnu__ command-line option. See 'automake --help' for all command-line options.
|
||||
|
||||
__LDADD__ and __CPPFLAGS__ (CFLAGS for C programs) specify flags used for **linking and compiling**);
|
||||
__LDADD__ and __CPPFLAGS__ (CFLAGS for C programs) specify flags used for **linking and compiling**;
|
||||
|
||||
bin_PROGRAMS is a (**space-separated**) __list of all binaries__ that will be built and installed by your package. We'll build just gdu here.
|
||||
|
||||
@@ -502,12 +510,11 @@ Makefile.am中定义的只是一些符合makefile语法的__变量__。
|
||||
|
||||
* 如果需要编译和安装多个可执行文件,则将它们的名称作为bin_PROGRAMS宏的参数。
|
||||
* 每个可执行文件都要用name_SOURCES宏定义它所依赖的源文件,automake会自动生成规则来编译和链接这些文件,最终生成一个可执行程序。
|
||||
* automake在读取makefile.am文件后,根据其中的变量设置,会生成一个makefile.in文件,该文件采用了makefile语法规则,与最终的makefile的__唯一区别__是含有将被configure脚本
|
||||
替换的变量。除了可执行程序或库目标(程序员在configure.in中相关变量指定的),automake还会安装GNU惯例,在makefile.in中添加一些标准规则。
|
||||
* automake在读取makefile.am文件后,根据其中的变量设置,会生成一个makefile.in文件,该文件采用了makefile语法规则,与最终的makefile的__唯一区别__是含有将被configure脚本 替换的变量。除了可执行程序或库目标(程序员在configure.in中相关变量指定的),automake还会安装GNU惯例,在makefile.in中添加一些标准规则。
|
||||
|
||||
man_MANS lists the man pages installed.
|
||||
|
||||
__noinst___HEADERS is the list of headers that **must go into a distribution** (a distribution is the .tar.gz file you distribute you program) **but are NOT installed** to @prefix@/include in the install step.
|
||||
__noinst___HEADERS is the list of headers that **must go into a distribution** (a distribution is the .tar.gz file you distribute you program) **but are NOT in**stalled to @prefix@/include in the install step.
|
||||
|
||||
EXTRA_DIST lists //additional files// that must be included in the distribution. The xpm files could be listed under noinst_HEADERS, it really makes no difference here.
|
||||
|
||||
@@ -516,7 +523,7 @@ Makefile.am中定义的只是一些符合makefile语法的__变量__。
|
||||
|
||||
Now we are ready to run automake (maybe). There some files missing, but automake will tell us about them, so relax. Run this (the **--add-missing** will add default files from the automake distribution when possible, complain about missing files when not)
|
||||
|
||||
automake --add-missing #--add-missing会从automake的安装文件中符号链接一些标准通用的文件到当前代码树中,但是有些项目特定的文件还需要自己创建。
|
||||
automake --add-missing #--add-missing会从automake的安装文件中符号链接一些标准通用的文件到当前代码树中,但是有些项目特定的文件还需要自己创建(NEWS, README, AUTHORS COPYING, ChangeLog)。
|
||||
|
||||
we obtain
|
||||
|
||||
@@ -533,9 +540,11 @@ we obtain
|
||||
automake: Makefile.am: required file `./AUTHORS' not found
|
||||
automake: Makefile.am: required file `./ChangeLog' not found #上面5个与具体项目相关,需要自己创建。
|
||||
|
||||
__install-sh__ is the shell replacement for the BSD **install** program, triggered by AC_PROG_INSTALL. __mkinstalldirs__ and __missing__ are similar shell scripts triggered by the AM_ macros in configure.in.
|
||||
__install-sh__ is the shell replacement for the BSD **install** program, triggered by **AC_PROG_INSTALL**. __mkinstalldirs__ and __missing__ are similar shell scripts triggered by the AM_ macros in configure.in.
|
||||
|
||||
INSTALL is the **automake standard installation instructions text**. COPYING is the GNU General Public License. COPYING was "needed" because we specified AUTOMAKE_OPTIONS = __gnu__. To work with bare requirements use AUTOMAKE_OPTIONS = __foreign__. In our example we stick with gnu, this is GPL'd program anyway.
|
||||
INSTALL is the **automake standard installation instructions text**. COPYING is the GNU General Public License. COPYING was "needed" because we specified AUTOMAKE_OPTIONS = __gnu__.
|
||||
|
||||
To work with bare requirements use AUTOMAKE_OPTIONS = __foreign__. In our example we stick with gnu, this is GPL'd program anyway.
|
||||
|
||||
However, the other required files couldn't be resolved. Because they are **package-specific**. To keep the gnu option, we have to write each of those files.
|
||||
|
||||
@@ -545,7 +554,7 @@ we obtain
|
||||
|
||||
Having written the missing files, we run automake again (no --add-missing required, all it could add has already been added), and it runs swiftly without errors.
|
||||
|
||||
You'll notice that the added files are symlinks to files in /usr/share/automake. This is fine for some people, since the make dist step that creates the distribution tarball packs as files, but if you will import you source tree into CVS (Concurrent Versioning System -- not needed but widely used, don't worry if you don't use it) you probably want to run automake with automake --add-missing __--copy__ to force file copying (if you want to do it now, you'll have to remove the symlinks first).
|
||||
You'll notice that the added files are **symlinks** to files in /usr/share/automake. This is fine for some people, since the make dist step that creates the distribution tarball packs as files, but if you will import you source tree into CVS (Concurrent Versioning System -- not needed but widely used, don't worry if you don't use it) you probably want to run automake with __automake --add-missing --copy__ to force file copying (if you want to do it now, you'll have to remove the symlinks first).
|
||||
|
||||
|
||||
===== Phew! Test it. =====
|
||||
@@ -558,20 +567,24 @@ we obtain
|
||||
make clean
|
||||
make distclean
|
||||
|
||||
The first one will compile the package. The dist target will create a __dist__ribution tarball -- the one you'll distribute to your users -- in our case it will create a tarball named **gdu-0.0.1.tar.gz**, __name and version are taken from the AM_INIT_AUTOMAKE macro__ in configure.in. This tarball complies with what users expect: it unpacks into a fresh directory of the same name (without the .tar.gz suffix).
|
||||
The first one will compile the package. The dist target will create a distribution tarball -- the one you'll distribute to your users -- in our case it will create a tarball named **gdu-0.0.1.tar.gz**, __name and version are taken from the AM_INIT_AUTOMAKE macro__ in configure.in. This tarball complies with what users expect: it unpacks into a fresh directory of the same name (without the .tar.gz suffix).
|
||||
|
||||
IMPORTANT! You should __always test__ the distribution tarball (by unpacking, compiling and installing), for it is usual to have files left out because you forgot to add graphic files, program headers or other needed files in the EXTRA_DIST or noinst_HEADERS variables in Makefile.am. Some files (README, INSTALL, etc.) are automatically included in the distribution if found, and running automake with 'automake --help' will show a list of all included-if-found filenames.
|
||||
|
||||
The clean target removes binaries and object files (.o).
|
||||
|
||||
The distclean target removes not only the binaries, but __all the configuration results__ created by the configure script. If you think your changes to configure.in or Makefile.am are not taking effect after running autoconf and automake, do a make distclean to clean any **cached** results. Also, you should do make distclean before importing your source tree into a CVS repository.
|
||||
The **distclean** target removes not only the binaries, but __all the configuration results__ created by the configure script. If you think your changes to configure.in or Makefile.am are not taking effect after running autoconf and automake, do a make distclean to clean any **cached** results. Also, you should do make distclean before importing your source tree into a CVS repository.
|
||||
|
||||
Other targets are install, uninstall and test.
|
||||
|
||||
===== 8. Makefile.am =====
|
||||
|
||||
__SUBDIRS__
|
||||
Automake'd projects can vary in directory topology. __Flat topologies__ include all source files in the project's top directory, like gdu. __Shallow topologies__ includes the sources in some subdirectories. The most common situation is having the source go inside a //src// directory instead of the top directory. __Deep topologies__ is what happens when you include your source in the top directory and libraries in subdirectories.
|
||||
|
||||
Automake'd projects can vary in directory topology.
|
||||
* __Flat topologies__ include all source files in the project's top directory, like gdu.
|
||||
* __Shallow topologies__ includes the sources in some subdirectories. The most common situation is having the source go inside a //src// directory instead of the top directory.
|
||||
* __Deep topologies__ is what happens when you include your source in the top directory and libraries in subdirectories.
|
||||
|
||||
To have a //multi-directory source tree//, specify all child directories in __the SUBDIRS variable__. Example:
|
||||
|
||||
@@ -580,12 +593,11 @@ we obtain
|
||||
Each subdirectory must have __its own Makefile.am__.
|
||||
|
||||
* Flat topologies: 所有的源文件(可执行文件和库文件的头文件,C/C++文件等)都放在项目的顶层目录中,configure.in, makefile.am, makefile.in等也放在该目录中。
|
||||
* Shallow topologies: 顶层目录只放配置文件(如整个项目的configure.in和makefile.am文件)和数据文件。所有的可执行文件和库文件源代码都按放在不同的目录中,目录中有自己的makefile.am文件,这些目录由上层
|
||||
的makefile.am中的SUBDIRS变量指定。
|
||||
* Shallow topologies: 顶层目录只放配置文件(如整个项目的configure.in和makefile.am文件)和数据文件。所有的可执行文件和库文件源代码都按放在不同的目录中,目录中有自己的makefile.am文件,这些目录由上层的makefile.am中的SUBDIRS变量指定。
|
||||
* Deep topologies: 可执行程序的源代码在当前目录,库文件源代码在单独的子目录中。
|
||||
|
||||
PROGRAMS
|
||||
__the *_PROGRAMS variables__ specify programs to be built. __bin___PROGRAMS list programs to be built and installed to @prefix@/bin, __sbin___PROGRAMS are built and installed to @prefix@/sbin; EXTRA_PROGRAMS are built but not installed.
|
||||
the *_PROGRAMS variables specify programs to be built. bin_PROGRAMS list programs to be built and installed to @prefix@/bin, sbin_PROGRAMS are built and installed to @prefix@/sbin; EXTRA_PROGRAMS are built but not installed.
|
||||
|
||||
Where Files Go ?
|
||||
For each program listed, __program_SOURCES__ lists the source files. __include_HEADERS__ lists headers that are installed to @prefix@/include. __EXTRA_DIST__ and __noinst_HEADERS__ files are included in the distribution but not installed.
|
||||
@@ -601,15 +613,18 @@ we obtain
|
||||
===== 9. Building Libraries: libtool =====
|
||||
In this section we show a very short example of **a shared library package**. __Automake will write a Makefile.in file that uses libtool to build it in a portable way__. Libtool is the way to build libraries. It will prevent you from dealing with arcane system idiosyncrasies by selecting **compiler and linker flags** and running system utilities as needed to integrate libraries seamlessly into the system.
|
||||
|
||||
libtool是一种在不同系统间可移植性地编译、安装和使用__库文件__的脚本工具。libtool本质上是GCC的封装程序,它的mode参数如compile/link/install分别和GCC的编译/链接/安装阶段相对应,automake会在需要时自动调用libtool脚本并向其传入合适的mode参数。libtool在编译库文件时会自动添加适合安装平台的参数如-c/-fPIC/-fpic等。libtool是个脚本文件,一般由automake自动地将其调用方法写入到生成的makefile中,__该脚本通常会放到源代码树中__,所以编译和安装该代码的系统不需要安装它。
|
||||
不同于M4和auto-系列工具,libtool对于使用了该方法的软件包而言,在编译和安装软件包的过程中是必需的。
|
||||
* libtool是一种在不同系统间可移植性地编译、安装和使用__库文件__的脚本工具。
|
||||
* libtool本质上是GCC的封装程序,它的mode参数如compile/link/install分别和GCC的编译/链接/安装阶段相对应,automake会在需要时自动调用libtool脚本并向其传入合适的mode参数。
|
||||
* libtool在编译库文件时会自动添加适合安装平台的参数如-c/-fPIC/-fpic等。
|
||||
* libtool是个脚本文件,一般由automake自动地将其调用方法写入到生成的makefile中,__该脚本通常会放到源代码树中__,所以编译和安装该代码的系统不需要安装它。
|
||||
* 不同于M4和auto-系列工具,libtool对于使用了该方法的软件包而言,在编译和安装软件包的过程中是必需的。
|
||||
|
||||
The example for this section is a set of 4 programs, one of which is a shared library. We'll use this same set of programs as an example for the next section.
|
||||
|
||||
The four programs are: dinnerd, libdinner, hungryhacker and vdinner.
|
||||
|
||||
* **dinnerd** is a daemon that acts as a server for the Dining Hackers protocol (this is an unofficial protocol, mostly useless, that I created for this example -- for a deeper explanation of protocol check the documentation in the dinnerd package). It manages a round table with at most 256 places, and waits for hackers (clients) to sit around. There are always N Chinese food boxes and N chop-sticks on the table, where N is the current number of hackers. Hackers need 2 chop-sticks to eat, so they all cannot eat at the same time. Competition for chop-sticks occurs, and hackers get angry and may beat each other if they can't get a chop-stick, and even die of starvation if they can't eat for too long. dinnerd provides two sub-protocols: one for hackers to connect and interact (request chop-sticks, etc.) and another for observers to watch the whole scene. Download source: dinnerd-1.0.0.tar.gz
|
||||
* **vdinner** screen-shot libdinner is a library that provides a set of functions to access a dinnerd server without the need to code directly with the Unix network API -- you don't need to know what bytes come and go in the connection, the library wraps the ugly things for you. Download source: libdinner-0.0.1.tar.gz
|
||||
* **libdinner** screen-shot libdinner is a library that provides a set of functions to access a dinnerd server without the need to code directly with the Unix network API -- you don't need to know what bytes come and go in the connection, the library wraps the ugly things for you. Download source: libdinner-0.0.1.tar.gz
|
||||
* **hungryhacke**r implements a client for the first sub-protocol. It implements a hacker that sleeps (in the sense of the Unix sleep() call, not human sleep) for a random amount of time, try to acquire chop-sticks, eat for a random amount of time, repeat. Download source: hungryhacker-0.0.1.tar.gz
|
||||
* **vdinner** implements a client for the second sub-protocol, it grabbing information about the status of the table from dinnerd using the library functions of libdinner and renders everything animated in 3D with the aid of the Mesa graphics library, as the screen-shot at the right shows. Download source: vdinner-0.0.1.tar.gz
|
||||
|
||||
@@ -617,7 +632,7 @@ libtool是一种在不同系统间可移植性地编译、安装和使用__库
|
||||
|
||||
The library source code is contained on two files: libdinner.c and dinner.h. The later will be installed under @prefix@/include and applications that link with the library will need to include it.
|
||||
|
||||
The first step to build a library is including the AM_PROG_LIBTOOL macro in configure.in. This is libdinner's configure.in file:
|
||||
The first step to build a library is including the **AM_PROG_LIBTOOL** macro in configure.in. This is libdinner's configure.in file:
|
||||
|
||||
**libdinner (Example 4): configure.in**
|
||||
|
||||
@@ -646,7 +661,10 @@ And this is libdinner's Makefile.am file:
|
||||
**libdinner (Example 4): Makefile.am**
|
||||
|
||||
AUTOMAKE_OPTIONS = __gnu__
|
||||
lib___LT__LIBRARIES = libdinner.__la #类似的还有安装到@prefix@/libexec的libexec_LTLIBRARIES__。libname.la是libtool的生成的库文件,在生成它的同时还会生成libname.so和libname.a等库文件,而libname.la是记录它们**实际安装位置的文本文件**。
|
||||
lib___LT__LIBRARIES = libdinner.la
|
||||
#类似的还有安装到@prefix@/libexec的libexec_LTLIBRARIES__。
|
||||
#libname.la是libtool使用的**文本文件**,在生成它的同时__还会生成__libname.so和libname.a等库文件。
|
||||
#libname.la文本文件记录了与name相关的所有库文件的名称及版本,依赖关系等。
|
||||
|
||||
__libdinner_la___SOURCES = libdinner.c #目标文件名中的点号必须用下划线代替,该宏一般只列出C/C++源文件,__不需要列出头文件__。头文件可以由CFLAGS标志给出。
|
||||
|
||||
@@ -654,8 +672,7 @@ And this is libdinner's Makefile.am file:
|
||||
|
||||
libdinner_la___LDFLAGS__ = **-version-info 0:0:0**
|
||||
|
||||
As usual, automake variable names have two parts. The lib in lib_LTLIBRARIES means the target will be installed to @prefix@/lib.
|
||||
And the __LT__ in LTLIBRARIES is from LibTool. **When target names have dashes (-) or dots (.), they're substituted for underscores, so we have libdinner_la_SOURCES instead of libdinner.la_SOURCES.**
|
||||
As usual, automake variable names have two parts. The lib in **lib_LTLIBRARIES** means the target will be installed to @prefix@/lib. And the __LT__ in LTLIBRARIES is from LibTool. **When target names have dashes (-) or dots (.), they're substituted for underscores, so we have libdinner_la_SOURCES instead of libdinner.la_SOURCES.**
|
||||
|
||||
We're using for the first time the include_HEADERS variable. It will place dinner.h in @prefix@/include.
|
||||
|
||||
@@ -668,10 +685,11 @@ And this is libdinner's Makefile.am file:
|
||||
* Current is the version of the **interface** the library implements. Whenever a new function is added, or its name changed, or the number or type of its parameters (the prototype -- in libraries we call this the function signature), this number goes up. And it goes up exactly by one.
|
||||
* Revision is the revision of the **implementation** of this interface, i.e., when you change the library by only modifying code inside the functions (fixing bugs, optimizing internal behavior, or adding/removing/changing signatures of functions that are private to the library -- used only internally) you raise the revision number only.
|
||||
* Age is the difference between the newest and oldest interface the library currently implements. Let's say you had 8 versions of your library's interface, 0 through 7. You are now on the 4th revision of the 8th interface, that is, 7:3:X (remember we start counting on zero). And when you had to make choices for what old interfaces you would keep support -- for backward compatibility purposes, you chose to keep support for interfaces 5, 6 and (obviously) the current, 7. The libtool version of your library would be 7:3:2 , because the Age is 7-5 = 2.
|
||||
AGE表示该库保证interface一致性的距离CURRENT的距离,如CURRENT=8, AGE=3则表示CURRENT为5,6,7,8的三个版本在interface级别是兼容的。
|
||||
|
||||
From the libtool documentation, verbatim:
|
||||
|
||||
**Never** try to set the interface numbers so that they correspond
|
||||
**Never** try to set **the interface numbers** so that they correspond
|
||||
to the release number of your package. This is an abuse that only
|
||||
fosters misunderstanding of the purpose of library versions. Instead,
|
||||
use the `-release' flag (*note Release numbers::.), but be warned that
|
||||
@@ -689,10 +707,9 @@ And this is libdinner's Makefile.am file:
|
||||
|
||||
The major difference between __shallow and deep is that in shallow packages you have only one configure.in, located in the top directory, and it will check everything that everything in the subdirectories need. Deep packages have a configure.in in each subdirectory, and it looks very much like an aggregate of programs which just happen to be distributed together.__
|
||||
|
||||
flat style 是将所有的源代码放到同一个目录下,整个工程只有一个configure.in和makefile.am文件。
|
||||
shallow style 有多个源代码目录,每个目录中都有makefile.am文件,整个工程只有一个位于顶层目录的configure.in文件,它负责检查__所有目录中__的源代码
|
||||
需要的系统特性。
|
||||
deep style 更像是将多个独立的工程目录添加到某个工程的顶层目录中,整个工程由多个configure.in文件,它们由顶层的configure.in控制。
|
||||
* flat style 是将所有的源代码放到同一个目录下,整个工程只有一个configure.in和makefile.am文件。
|
||||
* shallow style 有多个源代码目录,每个目录中都有makefile.am文件,整个工程只有一个位于顶层目录的configure.in文件,它负责检查系统环境并替换相应目录中的Makefile.in文件。
|
||||
* deep style 更像是将多个独立的工程目录添加到某个工程的顶层目录中,整个工程由多个configure.in文件,它们由顶层的configure.in控制。
|
||||
|
||||
**Shallow Example**
|
||||
Our shallow example is vdinner (Source code: vdinner-0.0.1.tar.gz). It has three important requirements: X, Mesa and libdinner. All the code is contained in the __src__ subdirectory. For shallow topologies, we write **a top-level configure.in** just like in a flat topology, except that __we must remember to AC_OUTPUT Makefiles for all subdirectories__ and __references to files may need directory prefixes__, such as src/vdinner.c. This is vdinner's configure.in:
|
||||
@@ -786,10 +803,10 @@ And this is the Makefile.am file in src:
|
||||
|
||||
It also has nothing different from what we discussed in the previous sections.
|
||||
|
||||
Automake must be **run from the top-level directory only**. __It will automatically descend into all SUBDIRS and create the associated Makefile.in files__. If you try running automake from an inner directory it will complain about the //lack of a configure.in there//, but you don't need one.
|
||||
Automake __must be__ run from the top-level directory only. __It will automatically descend into all SUBDIRS and create the associated Makefile.in files__. If you try running automake from an inner directory it will complain about the //lack of a configure.in there//, but you don't need one.
|
||||
|
||||
shallow style的package 必须在顶层目录运行automake工具,因为它需要读取configure.in文件中的信息,而该文件只单一地存在与顶层目录。
|
||||
shallow style的package的顶层makefile.am一般是比较简单的,因为该目录一般没有源代码文件。通过makefile.am中的SUBDIRS变量参数,automake会自动切换到该目录,将其中的makefile.am转换为makefile.in文件。__automake最终会搜集所有子目录中的makefile.in目标信息,将其写入顶层目录的makefile.in中(当然,具体如何编译各个目标,还要依赖相应目录中的makefile文件。)。configure脚本将检测到的值替换AC_OUT中列出的所有makefile.in文件,然后生成makefile文件。__
|
||||
* shallow style的package 必须在顶层目录运行automake工具,因为它需要读取configure.in文件中的信息,而该文件只单一地存在与顶层目录。
|
||||
* shallow style的package的顶层makefile.am一般是比较简单的,因为该目录一般没有源代码文件。通过makefile.am中的SUBDIRS变量参数,automake会自动切换到该目录,将其中的makefile.am转换为makefile.in文件。__automake最终会搜集所有子目录中的makefile.in目标信息,将其写入顶层目录的makefile.in中(当然,具体如何编译各个目标,还要依赖相应目录中的makefile文件。)。configure脚本将检测到的值替换AC_OUT中列出的所有makefile.in文件,然后生成makefile文件。__
|
||||
|
||||
**Deep Example**
|
||||
As an example of a deep topology, we'll put all four programs (dinnerd, libdinner, hungryhacker and vdinner) in one package. We'll call this all-in-one package the dinnersuite. First we create a dinnersuite directory and unpack the distribution tarballs into it. I'll also rename the unpacked directories to remove the version string from the name, but it's not needed. Now we have this directory tree:
|
||||
@@ -861,7 +878,8 @@ dinnersuite (Example 6): hungryhacker/configure.in
|
||||
|
||||
AC_CHECK_HEADERS(assert.h errno.h unistd.h time.h,,AC_MSG_ERROR([
|
||||
required header missing]))
|
||||
#删除了对libdinner库的检查。
|
||||
|
||||
#删除了对libdinner库的检查。
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
|
||||
@@ -880,7 +898,7 @@ dinnersuite (Example 6): hungryhacker/configure.in
|
||||
(a) Install your software in standard places. If you're using automake you're probably doing so already. Placing your binary under /var/coolstuff/lib/etc/boing/bin is much like not placing it anywhere at all. Doing a find / -name "foo" isn't practical and can take hours or even days to complete on systems that mount directories from a network (NFS is sooo transparent...)
|
||||
(b) **Provide version information**. The standard is to print a version string and exit without further action when the __-v or --version__ options are given in the command line. If you want to provide the version information in a different way, it's ok, but you must document it somewhere. A man page is probably the best place.
|
||||
(c) For libraries, __the most common way to check for presence is trying to link a small program(链接的目的只是检查该文件是否可以找到,而不是生成的程序是否可以正常工作)__. Document in the library changelogs the API changes. This way, if you introduced a float foo_bar(int,int) call in version X.Y.Z, users can detect versions >= X.Y.Z by trying to link a program that calls that function.
|
||||
(d) Many software packages (usually large ones) provide a __programname-config__ script that is installed together with the program, that will provide information on version, include file paths, library paths, features, etc. Examples are GTK+ (gtk-config), Gimp (gimp-config), XMMS (xmms-config) and Gnome (gnome-config). Below we show an example of output for the gtk-config script.
|
||||
(d) Many software packages (usually large ones) provide a __programname-config script __that is installed together with the program, that will provide information on version, include file paths, library paths, features, etc. Examples are GTK+ (gtk-config), Gimp (gimp-config), XMMS (xmms-config) and Gnome (gnome-config). Below we show an example of output for the gtk-config script.
|
||||
|
||||
//galadriel:~$ gtk-config//
|
||||
Usage: gtk-config [OPTIONS] [LIBRARIES]
|
||||
@@ -904,7 +922,7 @@ dinnersuite (Example 6): hungryhacker/configure.in
|
||||
|
||||
实际上是使用[[../pkgconfig.txt|pkg-config机制]]。
|
||||
|
||||
(e) Provide m4 macros to perform checks and tests on/for your software. The best behavior is to install these to the @prefix@/share/aclocal directory with the name yourpackage.m4. This way other developers may use the macros in their configure.in input files and aclocal will automatically look for the missing macros and place them in the aclocal.m4 of the distribution of the package that depends on yours.
|
||||
(e) Provide __m4 macros__ to perform checks and tests on/for your software. The best behavior is to install these to the @prefix@/share/aclocal directory with the name yourpackage.m4. This way other developers may use the macros in their configure.in input files and aclocal will automatically look for the missing macros and place them in the aclocal.m4 of the distribution of the package that depends on yours.
|
||||
|
||||
Compatibility. Make your software usable by the widest range of people possible. For example: when writing a library, it is quite easy to turn down C++ programmers by not enclosing the function prototypes in the public header files in extern "C" blocks. A way to do this in a portable manner is shown in the dinner.h header of libdinner, the example library of the libtool section.
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ Libtool 库可以是一个静态链接库,可以是一个动态链接库,也
|
||||
}
|
||||
|
||||
这个文件实现了一个函数 compress_file(),它接收一个文件名作为参数,然后对文件进行压缩,生成一个 .z结尾的压缩文件。在这个文件中使用了 compress()函数,这个函数是有由 libz 提供的。
|
||||
|
||||
从源文件建立 Libtool 库需要经过两个步骤,先建立 Libtool 对象文件,再建立 Libtool 库。
|
||||
|
||||
===== 建立 Libtool 对象文件 =====
|
||||
@@ -103,8 +104,7 @@ Libtool 库可以是一个静态链接库,可以是一个动态链接库,也
|
||||
$ libtool --mode=compile gcc -c foo.c
|
||||
|
||||
可以看到,**使用 Libtool 只需要将“传统”的命令 (gcc -c foo.c) 作为参数传递给 Libtool 即可**。
|
||||
在上面的命令中,libtool 使用 compile模式 (--mode=compile 选项 ),这是建立对象文件的模式,Libtool 还有其它的模式,后面将介绍。
|
||||
上面的命令输出如下 :
|
||||
在上面的命令中,libtool 使用 compile模式 (--mode=compile 选项 ),这是建立对象文件的模式,Libtool 还有其它的模式,后面将介绍。上面的命令输出如下 :
|
||||
|
||||
mkdir .libs
|
||||
gcc -c compress.c -fPIC -DPIC -o __.libs__/compress.o
|
||||
@@ -138,7 +138,7 @@ gcc -shared .libs/compress.o **-lz** -Wl,-soname -Wl,libcompress.so.0
|
||||
|
||||
可以看到,Libtool 自动的插入了**建立动态链接库需要的编译选项** -shared。并且,它也建立了**静态链接库** .libs/libcompress.a,后面我们将会介绍如何控制 Libtool 只建立需要的库。
|
||||
你可能会奇怪为什么建立的动态链接库有 .0 和 .0.0.0 这样的后缀,这里先不用理会它,后面在介绍 **Libtool 库版本信息**时将会解释这点。
|
||||
值得注意的是,Libtool 希望以后系统程序在链接时使用 libcompress.la 文件而不是直接使用 libcompress.a 和 libcompress.so 文件,如果你这样做,虽然可以,但会破坏 Libtool 库的可移植性。
|
||||
值得注意的是,Libtool 希望__以后系统程序在链接时使用 libcompress.la 文件__而不是直接使用 libcompress.a 和 libcompress.so 文件,如果你这样做,虽然可以,但会破坏 Libtool 库的可移植性。
|
||||
|
||||
===== 安装 Libtool 库 =====
|
||||
如果打算发布建立好的 Libtool 库,可以使用下面的命令安装它 :
|
||||
@@ -162,8 +162,7 @@ gcc -shared .libs/compress.o **-lz** -Wl,-soname -Wl,libcompress.so.0
|
||||
ranlib /tmp/libcompress.a
|
||||
...
|
||||
|
||||
可以看到它安装了真实的动态链接库和静态链接库,**同时也安装了 Libtool 库文件 libcompress.la**,这个文件可以被后续的 Libtool 命令使用。
|
||||
在安装完成之后,可能还需要做一些配置才能正确使用,Libtool 的 finish 模式可以在这方面给我们一些提示 :
|
||||
可以看到它安装了真实的动态链接库和静态链接库,**同时也安装了 Libtool 库文件 libcompress.la**,这个文件可以被后续的 Libtool 命令使用。在安装完成之后,可能还需要做一些配置才能正确使用,Libtool 的 finish 模式可以在这方面给我们一些提示 :
|
||||
|
||||
$ libtool -n --mode=finish /tmp
|
||||
|
||||
|
||||
@@ -6,10 +6,9 @@ Creation-Date: 2012-06-13T14:56:25+08:00
|
||||
Created Wednesday 13 June 2012
|
||||
http://blog.csdn.net/larntin2002/article/details/1821430
|
||||
|
||||
libtool常见于autoconf/automake,单独用的例子很少,所以我想仔细研究一下,为将来兄弟们看起来方便。
|
||||
|
||||
libtool常见于autoconf/automake,单独用的例子很少
|
||||
|
||||
==== 一。libtool的作用 ====
|
||||
==== 一 libtool的作用 ====
|
||||
offer a standard procedure for __creating__ shared libraries on different platforms
|
||||
libtool 是一个通用库支持__脚本__,将创建动态库的复杂性隐藏在统一、可移植的接口中,也就是说,你可以通过如下所示的标准方法,在不同平台上创建并调用动态库,我们可以认为libtool是gcc的一个抽象,也就是说,它包装了gcc或者其他的任何编译器,用户无需知道细节,只要告诉libtool说我需要要编译哪些库即可,并且,它只与libtool文件打交道,例如lo、la为后缀的文件。
|
||||
|
||||
@@ -63,7 +62,7 @@ libtool --mode=install install -c libhello.la /usr/local/lib/libhello.la
|
||||
/lib/ld-linux.so.2 (0x40000000)
|
||||
|
||||
|
||||
===== 5.install executable file =====
|
||||
===== 5.install executable file =====
|
||||
#libtool --mode=install cp hello /usr/local/bin/hello
|
||||
安装可执行程序。
|
||||
|
||||
|
||||
@@ -5,3 +5,123 @@ Creation-Date: 2012-06-13T14:30:22+08:00
|
||||
====== pkgconfig ======
|
||||
Created Wednesday 13 June 2012
|
||||
|
||||
====== linux里命令pkg-config工具的使用 ======
|
||||
Created Wednesday 13 June 2012
|
||||
http://www.91linux.com/html/article/program/cpp/20071207/8934.html
|
||||
|
||||
===== 一、编译和连接 =====
|
||||
|
||||
一般来说,如果库的头文件不在 /usr/include 目录中,那么在编译的时候需要用 -I 参数指定其路径。由于同一个库在不同系统上可能位于不同的目录下,用户安装库的时候也可以将库安装在不同的目录下,所以即使使用同一个库,由于库的路径的不同,造成了用 -I 参数指定的头文件的路径也可能不同,其结果就是造成了__编译命令界面的不统一__。如果使用 -L 参数,也会造成连接界面的不统一。__编译和连接界面不统一__会为库的使用带来麻烦。
|
||||
|
||||
为了解决编译和连接界面不统一的问题,人们找到了一些解决办法。**其基本思想就是:**__事先把库的位置信息等保存起来__**,需要的时候再通过特定的工具将其中有用的信息提取出来供编译和连接使用。这样,就可以做到编译和连接界面的一致性。**其中,目前最为常用的__库信息提取工具__就是下面介绍的 pkg-config。
|
||||
|
||||
pkg-config 是__通过库提供的一个 .pc 文件__获得库的各种必要信息的,包括版本信息、编译和连接需要的参数等。这些信息可以通过 pkg-config 提供的参数单独提取出来直接供编译器和连接器使用。
|
||||
|
||||
The pkgconfig package contains tools for passing the **include path and/or library paths** to build tools during the make file execution.
|
||||
|
||||
pkg-config is a function that returns **meta information** for the specified library.
|
||||
|
||||
The default setting for __PKG_CONFIG_PATH__ is **/usr/lib/pkgconfig** because of the prefix we use to install pkgconfig. You may add to PKG_CONFIG_PATH by exporting additional paths on your system where pkgconfig files are installed. Note that PKG_CONFIG_PATH is **only needed when compiling packages**, not during run-time.
|
||||
|
||||
在默认情况下,每个支持 pkg-config 的库对应的 .pc 文件在安装后都位于**安装目录中的 lib/pkgconfig 目录**下。例如,我们在上面已经将 Glib 安装在 /opt/gtk 目录下了,那么这个 Glib 库对应的 .pc 文件是 /opt/gtk/lib/pkgconfig 目录下一个叫 glib-2.0.pc 的文件:
|
||||
|
||||
prefix=/opt/gtk/
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
glib_genmarshal=glib-genmarshal
|
||||
gobject_query=gobject-query
|
||||
glib_mkenums=glib-mkenums
|
||||
|
||||
Name: GLib
|
||||
Description: C Utility Library
|
||||
Version: 2.12.13
|
||||
Libs: -L${libdir} -lglib-2.0
|
||||
Cflags: -I${includedir}/glib-2.0 -I${libdir}/glib-2.0/include
|
||||
|
||||
在利用源代码中提供的configure脚本配置该库时,.pc文件中的变量会被实际值所代替(针对提供.pc文件公其它软件包使用的当前源代码而言),如${prefix}会被该库的实际安装位置所代替。
|
||||
|
||||
使用 pkg-config 的 __--cflags__ 参数可以给出在编译时所需要的选项,而 __--libs 参数__可以给出连接时的选项。例如,假设一个 sample.c 的程序用到了 Glib 库,就可以这样编译:
|
||||
|
||||
$ gcc -c `pkg-config --cflags **glib-2.0**` sample.c
|
||||
|
||||
然后这样连接:
|
||||
|
||||
$ gcc sample.o -o sample `pkg-config --libs glib-2.0`
|
||||
|
||||
或者上面两步也可以合并为以下一步:
|
||||
|
||||
$ gcc sample.c -o sample `pkg-config --cflags --libs glib-2.0`
|
||||
|
||||
可以看到:**由于使用了 pkg-config 工具来获得库的选项,所以不论库安装在什么目录下,都可以使用相同的编译和连接命令,带来了编译和连接界面的统一**。
|
||||
|
||||
使用 pkg-config 工具提取库的编译和连接参数有两个基本的前提:
|
||||
|
||||
* 库本身在安装的时候必须提供一个相应的 .pc 文件。不这样做的库说明不支持 pkg-config 工具的使用。
|
||||
* pkg-config 工具必须知道要到哪里去寻找此 .pc 文件。
|
||||
|
||||
**GTK+ 及其依赖库支持使用 pkg-config 工具**,所以剩下的问题就是如何告诉 pkg-config 到哪里去寻找库对应的 .pc 文件,这也是通过设置__搜索路径__来解决的。
|
||||
|
||||
对于支持 pkg-config 工具的 GTK+ 及其依赖库来说,库的头文件的搜索路径的设置变成了对 .pc 文件搜索路径的设置。.pc 文件的搜索路径是通过环境变量 __PKG_CONFIG_PATH__ 来设置的,pkg-config 将按照设置路径的先后顺序进行搜索,直到找到指定的 .pc 文件为止。
|
||||
|
||||
安装完 Glib 后,在 bash 中应该进行如下设置:
|
||||
|
||||
$ export PKG_CONFIG_PATH=**/opt/gtk/lib/pkgconfig**:$PKG_CONFIG_PATH
|
||||
|
||||
可以执行下面的命令检查是否 /opt/gtk/lib/pkgconfig 路径已经设置在 PKG_CONFIG_PATH 环境变量中:
|
||||
|
||||
$ echo $PKG_CONFIG_PATH
|
||||
|
||||
这样设置之后,使用 Glib 库的其它程序或库__在编译的时候__ pkg-config 就知道首先要到 /opt/gtk/lib/pkgconfig 这个目录中去寻找 glib-2.0.pc 了(GTK+ 和其它的依赖库的 .pc 文件也将拷贝到这里,也会首先到这里搜索它们对应的 .pc 文件)。之后,通过 pkg-config 就可以把其中库的编译和连接参数提取出来供程序在编译和连接时使用。另外还需要注意的是:环境变量的设置只对当前的终端窗口有效。如果到了没有进行上述设置的终端窗口中,pkg-config 将找不到新安装的 glib-2.0.pc 文件、从而可能使后面进行的安装(如 Glib 之后的 Atk 的安装)无法进行。
|
||||
|
||||
在我们采用的安装方案中,由于是使用环境变量对 GTK+ 及其依赖库进行的设置,所以当系统重新启动、或者新开一个终端窗口之后,如果想使用新安装的 GTK+ 库,需要如上面那样重新设置 PKG_CONFIG_PATH 和 LD_LIBRARY_PATH 环境变量。
|
||||
|
||||
这种使用 GTK+ 的方法,在使用之前多了一个对库进行设置的过程。虽然显得稍微繁琐了一些,但却是一种最安全的使用 GTK+ 库的方式,不会对系统上已经存在的使用了 GTK+ 库的程序(比如 GNOME 桌面)带来任何冲击。
|
||||
|
||||
为了使库的设置变得简单一些,可以把下面的这两句设置保存到一个文件中(比如 set_gtk-2.10 文件):
|
||||
|
||||
export PKG_CONFIG_PATH=/opt/gtk/lib/pkgconfig:$PKG_CONFIG_PATH
|
||||
export **LD_LIBRARY_PATH**=/opt/gtk/lib:$LD_LIBRARY_PATH
|
||||
|
||||
之后,就可以用下面的方法进行库的设置了(其中的 source 命令也可以用 . 代替):
|
||||
|
||||
$ source set_gtk-2.10
|
||||
|
||||
只有在用新版的 GTK+ 库开发应用程序、或者运行使用了新版 GTK+ 库的程序的时候,才有必要进行上述设置。
|
||||
|
||||
如果想避免使用 GTK+ 库之前上述设置的麻烦,可以把上面两个环境变量的设置在系统的配置文件中(如 /etc/profile)或者自己的用户配置文件中(如 ~/.bash_profile) ;库的搜索路径也可以设置在 /etc/ld.so.conf 文件中,等等。这种设置在系统启动时会生效,从而会导致使用 GTK+ 的程序使用新版的 GTK+ 运行库,这有可能会带来一些问题。当然,如果你发现用新版的 GTK+ 代替旧版没有什么问题的话,使用这种设置方式是比较方便的。加入到~/.bashrc中,例如:
|
||||
PKG_CONFIG_PATH=/opt/gtk/lib/pkgconfig
|
||||
重启之后:
|
||||
[root@localhost ~]# echo $PKG_CONFIG_PATH
|
||||
/opt/gtk/lib/pkgconfig
|
||||
|
||||
|
||||
===== 二、运行时 =====
|
||||
|
||||
库文件在连接(静态库和共享库)和运行(__仅限于使用共享库的程序__)时被使用,其搜索路径是在系统中进行设置的。一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,所以使用这两个目录中的库时不需要进行设置搜索路径即可直接使用。对于处于默认库搜索路径之外的库,需要将库的位置添加到 库的搜索路径之中。设置库文件的搜索路径有下列两种方式,可任选其一使用:
|
||||
|
||||
* 在环境变量 LD_LIBRARY_PATH 中指明库的搜索路径。
|
||||
* 在 /etc/ld.so.conf 文件中添加库的搜索路径。
|
||||
|
||||
将自己可能存放库文件的路径都加入到/etc/ld.so.conf中是明智的选择 ^_^
|
||||
添加方法也极其简单,将库文件的绝对路径直接写进去就OK了,一行一个。例如:
|
||||
/usr/X11R6/lib
|
||||
/usr/local/lib
|
||||
/opt/lib
|
||||
|
||||
需要注意的是:第二种搜索路径的设置方式对于程序连接时的库(包括共享库和静态库)的定位已经足够了,但是对于使用了共享库的程序的执行还是不够的。这是 因为为了加快程序执行时对共享库的定位速度,避免使用搜索路径查找共享库的低效率,所以是直接读取库列表文件 __/etc/ld.so.cache__ 从中进行搜索的。/etc/ld.so.cache 是一个非文本的数据文件,不能直接编辑,它是根据 /etc/ld.so.conf 中设置的搜索路径由 __/sbin/ldconfig__ 命令将这些搜索路径下的共享库文件集中在一起而生成的(ldconfig 命令要以 root 权限执行)。
|
||||
|
||||
因此,为了保证程序执行时对库的定位,在 /etc/ld.so.conf 中进行了库搜索路径的设置之后,还必须__要运行 /sbin/ldconfig 命令更新 /etc/ld.so.cache__ 文件之后才可以。ldconfig ,简单的说,它的作用就是将/etc/ld.so.conf列出的路径下的库文件 缓存到/etc/ld.so.cache 以供使用。因此当安装完一些库文件,(例如刚安装好glib),或者修改ld.so.conf增加新的库路径后,需要运行一下 /sbin/ldconfig使所有的库文件都被缓存到ld.so.cache中,如果没做,即使库文件明明就在/usr/lib下的,也是不会被使用 的,结果编译过程中抱错,缺少xxx库,去查看发现明明就在那放着,搞的想大骂computer蠢猪一个。 ^_^
|
||||
|
||||
在程序连接时,对于库文件(静态库和共享库)的搜索路径,除了上面的设置方式之外,还可以通过 -L 参数显式指定。因为用 -L 设置的路径将被优先搜索,所以在连接的时候通常都会以这种方式直接指定要连接的库的路径。
|
||||
|
||||
前面已经说明过了,库搜索路径的设置有两种方式:在环境变量 LD_LIBRARY_PATH 中设置以及在 /etc/ld.so.conf 文件中设置。其中,第二种设置方式需要 root 权限,以改变 /etc/ld.so.conf 文件并执行 /sbin/ldconfig 命令。而且,当系统重新启动后,所有的基于 GTK2 的程序在运行时都将使用新安装的 GTK+ 库。不幸的是,由于 GTK+ 版本的改变,这有时会给应用程序带来兼容性的问题,造成某些程序运行不正常。为了避免出现上面的这些情况,在 GTK+ 及其依赖库的安装过程中对于库的搜索路径的设置将采用第一种方式进行。这种设置方式不需要 root 权限,设置也简单:
|
||||
|
||||
$ export LD_LIBRARY_PATH=/opt/gtk/lib:$LD_LIBRARY_PATH
|
||||
|
||||
可以用下面的命令查看 LD_LIBRAY_PATH 的设置内容:
|
||||
|
||||
$ echo $LD_LIBRARY_PATH
|
||||
|
||||
至此,库的两种设置就完成了。
|
||||
|
||||
@@ -18,7 +18,6 @@ http://blog.csdn.net/absurd/article/details/599813
|
||||
|
||||
以上的场景并非虚构,我都经历过好几次,明明在本机上好好的,在别人的机器上连编译都过不去。可能两人的操作系统一模一样,需要的库都安装上,只是由于个人喜好不同,安装在不同的目录而已。遇到这种情况,每次都技巧性的绕过去了,用的补丁型的方法,心里老惦记其它地方能不能工作。
|
||||
|
||||
|
||||
今天我们要介绍的pkgconfig,为解决以上问题提供了一个优美方案。从此,你再也不为此担忧了。Pkgconfig提供了下面几个功能:
|
||||
|
||||
1. 检查库的版本号。如果所需要的库的版本不满足要求,它会打印出错误信息,避免链接错误版本的库文件。
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-06-13T14:41:11+08:00
|
||||
|
||||
====== linux里命令pkg-config工具的使用 ======
|
||||
Created Wednesday 13 June 2012
|
||||
http://www.91linux.com/html/article/program/cpp/20071207/8934.html
|
||||
|
||||
===== 一、编译和连接 =====
|
||||
|
||||
一般来说,如果库的头文件不在 /usr/include 目录中,那么在编译的时候需要用 -I 参数指定其路径。由于同一个库在不同系统上可能位于不同的目录下,用户安装库的时候也可以将库安装在不同的目录下,所以即使使用同一个库,由于库的路径的不同,造成了用 -I 参数指定的头文件的路径也可能不同,其结果就是造成了__编译命令界面的不统一__。如果使用 -L 参数,也会造成连接界面的不统一。__编译和连接界面不统一__会为库的使用带来麻烦。
|
||||
|
||||
为了解决编译和连接界面不统一的问题,人们找到了一些解决办法。**其基本思想就是:**__事先把库的位置信息等保存起来__**,需要的时候再通过特定的工具将其中有用的 信息提取出来供编译和连接使用。这样,就可以做到编译和连接界面的一致性。**其中,目前最为常用的__库信息提取工具__就是下面介绍的 pkg-config。
|
||||
|
||||
pkg-config 是通过__库提供的一个 .pc 文件__获得库的各种必要信息的,包括版本信息、编译和连接需要的参数等。这些信息可以通过 pkg-config 提供的参数单独提取出来直接供编译器和连接器使用。
|
||||
|
||||
The pkgconfig package contains tools for passing the **include path and/or library paths** to build tools during the make file execution.
|
||||
|
||||
pkg-config is a function that returns **meta information** for the specified library.
|
||||
|
||||
The default setting for __PKG_CONFIG_PATH__ is **/usr/lib/pkgconfig** because of the prefix we use to install pkgconfig. You may add to PKG_CONFIG_PATH by exporting additional paths on your system where pkgconfig files are installed. Note that PKG_CONFIG_PATH is **only needed when compiling packages**, not during run-time.
|
||||
|
||||
在默认情况下,每个支持 pkg-config 的库对应的 .pc 文件在安装后都位于安装目录中的 lib/pkgconfig 目录下。例如,我们在上面已经将 Glib 安装在 /opt/gtk 目录下了,那么这个 Glib 库对应的 .pc 文件是 /opt/gtk/lib/pkgconfig 目录下一个叫 glib-2.0.pc 的文件:
|
||||
|
||||
prefix=/opt/gtk/
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
glib_genmarshal=glib-genmarshal
|
||||
gobject_query=gobject-query
|
||||
glib_mkenums=glib-mkenums
|
||||
|
||||
Name: GLib
|
||||
Description: C Utility Library
|
||||
Version: 2.12.13
|
||||
Libs: -L${libdir} -lglib-2.0
|
||||
Cflags: -I${includedir}/glib-2.0 -I${libdir}/glib-2.0/include
|
||||
|
||||
在利用源代码中提供的configure脚本配置该库时,.pc文件中的变量会被实际值所代替,如${prefix}会被该库的实际安装位置所代替。
|
||||
|
||||
使用 pkg-config 的 __--cflags__ 参数可以给出在编译时所需要的选项,而 __--libs 参数__可以给出连接时的选项。例如,假设一个 sample.c 的程序用到了 Glib 库,就可以这样编译:
|
||||
|
||||
$ gcc -c `pkg-config --cflags **glib-2.0**` sample.c
|
||||
|
||||
然后这样连接:
|
||||
|
||||
$ gcc sample.o -o sample `pkg-config --libs glib-2.0`
|
||||
|
||||
或者上面两步也可以合并为以下一步:
|
||||
|
||||
$ gcc sample.c -o sample `pkg-config --cflags --libs glib-2.0`
|
||||
|
||||
可以看到:**由于使用了 pkg-config 工具来获得库的选项,所以不论库安装在什么目录下,都可以使用相同的编译和连接命令,带来了编译和连接界面的统一**。
|
||||
|
||||
使用 pkg-config 工具提取库的编译和连接参数有两个基本的前提:
|
||||
|
||||
* 库本身在安装的时候必须提供一个相应的 .pc 文件。不这样做的库说明不支持 pkg-config 工具的使用。
|
||||
* pkg-config 工具必须知道要到哪里去寻找此 .pc 文件。
|
||||
|
||||
**GTK+ 及其依赖库支持使用 pkg-config 工具**,所以剩下的问题就是如何告诉 pkg-config 到哪里去寻找库对应的 .pc 文件,这也是通过设置__搜索路径__来解决的。
|
||||
对于支持 pkg-config 工具的 GTK+ 及其依赖库来说,库的头文件的搜索路径的设置变成了对 .pc 文件搜索路径的设置。.pc 文件的搜索路径是通过环境变量 __PKG_CONFIG_PATH__ 来设置的,pkg-config 将按照设置路径的先后顺序进行搜索,直到找到指定的 .pc 文件为止。
|
||||
|
||||
安装完 Glib 后,在 bash 中应该进行如下设置:
|
||||
|
||||
$ export PKG_CONFIG_PATH=**/opt/gtk/lib/pkgconfig**:$PKG_CONFIG_PATH
|
||||
|
||||
可以执行下面的命令检查是否 /opt/gtk/lib/pkgconfig 路径已经设置在 PKG_CONFIG_PATH 环境变量中:
|
||||
|
||||
$ echo $PKG_CONFIG_PATH
|
||||
|
||||
这样设置之后,使用 Glib 库的其它程序或库__在编译的时候__ pkg-config 就知道首先要到 /opt/gtk/lib/pkgconfig 这个目录中去寻找 glib-2.0.pc 了(GTK+ 和其它的依赖库的 .pc 文件也将拷贝到这里,也会首先到这里搜索它们对应的 .pc 文件)。之后,通过 pkg-config 就可以把其中库的编译和连接参数提取出来供程序在编译和连接时使用。另外还需要注意的是:环境变量的设置只对当前的终端窗口有效。如果到了没有进行上述设置的终端窗口中,pkg-config 将找不到新安装的 glib-2.0.pc 文件、从而可能使后面进行的安装(如 Glib 之后的 Atk 的安装)无法进行。
|
||||
|
||||
在我们采用的安装方案中,由于是使用环境变量对 GTK+ 及其依赖库进行的设置,所以当系统重新启动、或者新开一个终端窗口之后,如果想使用新安装的 GTK+ 库,需要如上面那样重新设置 PKG_CONFIG_PATH 和 LD_LIBRARY_PATH 环境变量。
|
||||
|
||||
这种使用 GTK+ 的方法,在使用之前多了一个对库进行设置的过程。虽然显得稍微繁琐了一些,但却是一种最安全的使用 GTK+ 库的方式,不会对系统上已经存在的使用了 GTK+ 库的程序(比如 GNOME 桌面)带来任何冲击。
|
||||
|
||||
为了使库的设置变得简单一些,可以把下面的这两句设置保存到一个文件中(比如 set_gtk-2.10 文件):
|
||||
|
||||
export PKG_CONFIG_PATH=/opt/gtk/lib/pkgconfig:$PKG_CONFIG_PATH
|
||||
export **LD_LIBRARY_PATH**=/opt/gtk/lib:$LD_LIBRARY_PATH
|
||||
|
||||
之后,就可以用下面的方法进行库的设置了(其中的 source 命令也可以用 . 代替):
|
||||
|
||||
$ source set_gtk-2.10
|
||||
|
||||
只有在用新版的 GTK+ 库开发应用程序、或者运行使用了新版 GTK+ 库的程序的时候,才有必要进行上述设置。
|
||||
|
||||
如果想避免使用 GTK+ 库之前上述设置的麻烦,可以把上面两个环境变量的设置在系统的配置文件中(如 /etc/profile)或者自己的用户配置文件中(如 ~/.bash_profile) ;库的搜索路径也可以设置在 /etc/ld.so.conf 文件中,等等。这种设置在系统启动时会生效,从而会导致使用 GTK+ 的程序使用新版的 GTK+ 运行库,这有可能会带来一些问题。当然,如果你发现用新版的 GTK+ 代替旧版没有什么问题的话,使用这种设置方式是比较方便的。加入到~/.bashrc中,例如:
|
||||
PKG_CONFIG_PATH=/opt/gtk/lib/pkgconfig
|
||||
重启之后:
|
||||
[root@localhost ~]# echo $PKG_CONFIG_PATH
|
||||
/opt/gtk/lib/pkgconfig
|
||||
|
||||
|
||||
===== 二、运行时 =====
|
||||
|
||||
库文件在连接(静态库和共享库)和运行(__仅限于使用共享库的程序__)时被使用,其搜索路径是在系统中进行设置的。一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,所以使用这两个目录中的库时不需要进行设置搜索路径即可直接使用。对于处于默认库搜索路径之外的库,需要将库的位置添加到 库的搜索路径之中。设置库文件的搜索路径有下列两种方式,可任选其一使用:
|
||||
|
||||
* 在环境变量 LD_LIBRARY_PATH 中指明库的搜索路径。
|
||||
* 在 /etc/ld.so.conf 文件中添加库的搜索路径。
|
||||
|
||||
将自己可能存放库文件的路径都加入到/etc/ld.so.conf中是明智的选择 ^_^
|
||||
添加方法也极其简单,将库文件的绝对路径直接写进去就OK了,一行一个。例如:
|
||||
/usr/X11R6/lib
|
||||
/usr/local/lib
|
||||
/opt/lib
|
||||
|
||||
需要注意的是:第二种搜索路径的设置方式对于程序连接时的库(包括共享库和静态库)的定位已经足够了,但是对于使用了共享库的程序的执行还是不够的。这是 因为为了加快程序执行时对共享库的定位速度,避免使用搜索路径查找共享库的低效率,所以是直接读取库列表文件 __/etc/ld.so.cache__ 从中进行搜索的。/etc/ld.so.cache 是一个非文本的数据文件,不能直接编辑,它是根据 /etc/ld.so.conf 中设置的搜索路径由 __/sbin/ldconfig__ 命令将这些搜索路径下的共享库文件集中在一起而生成的(ldconfig 命令要以 root 权限执行)。
|
||||
|
||||
因此,为了保证程序执行时对库的定位,在 /etc/ld.so.conf 中进行了库搜索路径的设置之后,还必须__要运行 /sbin/ldconfig 命令更新 /etc/ld.so.cache__ 文件之后才可以。ldconfig ,简单的说,它的作用就是将/etc/ld.so.conf列出的路径下的库文件 缓存到/etc/ld.so.cache 以供使用。因此当安装完一些库文件,(例如刚安装好glib),或者修改ld.so.conf增加新的库路径后,需要运行一下 /sbin/ldconfig使所有的库文件都被缓存到ld.so.cache中,如果没做,即使库文件明明就在/usr/lib下的,也是不会被使用 的,结果编译过程中抱错,缺少xxx库,去查看发现明明就在那放着,搞的想大骂computer蠢猪一个。 ^_^
|
||||
|
||||
在程序连接时,对于库文件(静态库和共享库)的搜索路径,除了上面的设置方式之外,还可以通过 -L 参数显式指定。因为用 -L 设置的路径将被优先搜索,所以在连接的时候通常都会以这种方式直接指定要连接的库的路径。
|
||||
|
||||
前面已经说明过了,库搜索路径的设置有两种方式:在环境变量 LD_LIBRARY_PATH 中设置以及在 /etc/ld.so.conf 文件中设置。其中,第二种设置方式需要 root 权限,以改变 /etc/ld.so.conf 文件并执行 /sbin/ldconfig 命令。而且,当系统重新启动后,所有的基于 GTK2 的程序在运行时都将使用新安装的 GTK+ 库。不幸的是,由于 GTK+ 版本的改变,这有时会给应用程序带来兼容性的问题,造成某些程序运行不正常。为了避免出现上面的这些情况,在 GTK+ 及其依赖库的安装过程中对于库的搜索路径的设置将采用第一种方式进行。这种设置方式不需要 root 权限,设置也简单:
|
||||
|
||||
$ export LD_LIBRARY_PATH=/opt/gtk/lib:$LD_LIBRARY_PATH
|
||||
|
||||
可以用下面的命令查看 LD_LIBRAY_PATH 的设置内容:
|
||||
|
||||
$ echo $LD_LIBRARY_PATH
|
||||
|
||||
至此,库的两种设置就完成了。
|
||||
127
Zim/Utils/工具链/使用GNU_Autotools自動編譯項目.txt
Normal file
127
Zim/Utils/工具链/使用GNU_Autotools自動編譯項目.txt
Normal file
@@ -0,0 +1,127 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-31T19:53:42+08:00
|
||||
|
||||
====== 使用GNU Autotools自動編譯項目 ======
|
||||
Created Monday 31 December 2012
|
||||
|
||||
http://www.cnblogs.com/crazyhack/archive/2011/12/17/2291410.html
|
||||
為了駕馭GNU Autotools這頭猛獸,我們先來驗明它的真身:
|
||||
{{./1.png}}
|
||||
圖中橢圓形狀的就是gnu autotools里的主要工具了,包括1autoscan2aclocal3autoheader4automake5autoconf等.而方形形狀只有Makefile.am和configure.ac是需要我們寫的,别的方框里除了Makefile是最終的配置文件,其它都是中間文件。(Makefile文件是由6configure生成的)
|
||||
整體流程紀錄如下:
|
||||
|
||||
0.添加src目錄,將項目源碼放入該目錄中
|
||||
|
||||
1.進入項目根目錄執行命令,以生成configure.scan文件:
|
||||
|
||||
autoscan
|
||||
|
||||
2.修改configure.scan文件為configure.ac文件,編輯configure.ac文件:
|
||||
|
||||
mv configure.scan configure.ac
|
||||
|
||||
vim configure.ac
|
||||
|
||||
3.編輯根目錄下的Makefile.am文件
|
||||
|
||||
vim Makefile.am
|
||||
|
||||
4.建立autogen.sh文件,將aclocal、autoheader、automake、autoconf等命令添加到腳本中。
|
||||
|
||||
5.在根目錄執行
|
||||
|
||||
./autogen.sh
|
||||
|
||||
6.用[./configure](執行後生成Makefile文件 )、[make]、[sudo make install]安裝並運行執行檔.
|
||||
|
||||
PS:其中0~5為開發人員執行的步驟,6為測試人員和用戶執行的步驟。
|
||||
|
||||
0.在項目根目錄建立src文件夾,內容如下:
|
||||
|
||||
image
|
||||
1.在項目根目錄運行autoscan命令:
|
||||
|
||||
image
|
||||
|
||||
可以看到生成了autoscan.log,autom4te.cache目錄以及我們需要的configure.scan文件
|
||||
2.修改configure.scan文件為configure.ac,執行:
|
||||
|
||||
mv configure.scan configure.ac
|
||||
|
||||
vim configure.ac
|
||||
|
||||
為了方便,我已經事先寫好了configure.ac文件,使用vimdiff命令對比一下修改的部分:
|
||||
|
||||
image
|
||||
|
||||
修改的部分一目了然:)
|
||||
3.在根目錄添加Makefile.am文件:
|
||||
|
||||
vim Makefile.am
|
||||
|
||||
image
|
||||
|
||||
其中,bin_PROGRAMS後面是需要生成的執行文件,如有多個,可以用空格隔開,而xxx_SOURCES後面的就是編譯時需要的源文件了,直接指定源碼在src目錄中,這樣configure.ac的AC_CONFIG_FILES參數就可以寫成AC_CONFIG_FILES([Makefile])了,而不需要在參數中添加更多目錄下的Makefile。否則就要寫成:
|
||||
|
||||
image
|
||||
4.建立autogen.sh文件,添加我們需要後續執行的命令aclocal、autoheader、automake、autocon:
|
||||
|
||||
vim autogen.sh
|
||||
|
||||
image
|
||||
|
||||
下面解釋一下各命令:
|
||||
|
||||
1)aclocal:根據configure.ac的定義,將需要使用的m4宏定義複製到aclocal.m4裡面。缺省時,搜索m4宏是從autoconf的安裝目錄和系統的aclocal目錄。
|
||||
|
||||
2)autoheader:負責生成config.h.in文件,這裡面的C語言宏定義通過解析configure.ac生成。
|
||||
|
||||
3)automake:處理Makefile.am,從而生成Makefile.in。automake提供了三個軟件等級:foreign、gnu和gnits。默認等級是gnu,這裡我們使用foreign等級,它只檢測必須的文件。在執行時使用—add-missing選項可以讓automake自動添加(默認採用符號連結),如加上—copy選項可以使用複製方式,本例中,automake的命令如下:
|
||||
|
||||
automake –foreign –add-missing –copy
|
||||
|
||||
4)autoconf:生成configure文件,configure是一個shell script,可以自動設定原始程式以符合不同平台上Unix系統的特性,並且根據系統參數及環境產生合適的Makefile文件或C的頭文件,讓源代碼可以在這些不同的平台上被編譯出來。
|
||||
5.退回根目錄,在終端執行
|
||||
|
||||
./autogen.sh
|
||||
|
||||
PS:如果看到下面的提示是正常的,因為我們的項目只是用於測試,所以不要求按照GNU的標準來添加所有需要的文件
|
||||
|
||||
Makefile.am: required file `./NEWS' not found
|
||||
Makefile.am: required file `./README' not found
|
||||
Makefile.am: required file `./AUTHORS' not found
|
||||
Makefile.am: required file `./ChangeLog' not found
|
||||
6.用三部曲生成需要的執行檔:
|
||||
|
||||
1)./configure:
|
||||
|
||||
image
|
||||
|
||||
image
|
||||
|
||||
看到Makefile文件就說明配置項目成功了
|
||||
|
||||
2)make:
|
||||
|
||||
image
|
||||
|
||||
出現很多錯誤不要管它,因為我只在testgenfilemap.c中輸入了打印hello world!的源碼,再用tree命令可以看到生成了testgenfilemap.o文件和二進制文件testgenfilemap
|
||||
|
||||
image
|
||||
|
||||
再輸入./testgenfilemap呢?
|
||||
|
||||
image
|
||||
|
||||
哈哈,恭喜你,成功了!
|
||||
|
||||
3)如果需要安裝到系統目錄,請運行sudo make install
|
||||
|
||||
參考文章:
|
||||
|
||||
1.http://www.ibm.com/developerworks/cn/linux/l-makefile/
|
||||
|
||||
2.http://tetralet.luna.com.tw/index.php?op=ViewArticle&articleId=200&blogId=1
|
||||
|
||||
3.http://blog.csdn.net/zhbaoq/article/details/750199
|
||||
BIN
Zim/Utils/工具链/使用GNU_Autotools自動編譯項目/1.png
Normal file
BIN
Zim/Utils/工具链/使用GNU_Autotools自動編譯項目/1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
Reference in New Issue
Block a user