本文只在Linux平台下可用,使用环境为 Ubuntu 16.04 。 作为备忘,以应对不时之需,行文粗浅,如有纰漏,欢迎指正。
一、下载两个工具的源码。
bsdiff:http://www.daemonology.net/bsdiff/bsdiff-4.3.tar.gz
bzip2:http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz
二、进入bsdiff-4.3目录下执行make命令,会出现错误:
$ make
Makefile:13: *** missing separator。 停止。
三、错误的意思是Makefile第13行缺少分隔符,在第13行和第15行前面添加一个Tab分隔符即可。如下:
CFLAGS += -O3 -lbz2
PREFIX ?= /usr/local
INSTALL_PROGRAM ?= ${INSTALL} -c -s -m 555
INSTALL_MAN ?= ${INSTALL} -c -m 444
all: bsdiff bspatch
bsdiff: bsdiff.c
bspatch: bspatch.c
install:
${INSTALL_PROGRAM} bsdiff bspatch ${PREFIX}/bin
.ifndef WITHOUT_MAN
${INSTALL_MAN} bsdiff.1 bspatch.1 ${PREFIX}/man/man1
.endif
四、修改完成后再次执行make命令,发现又出现错误:
$ make
cc -O3 -lbz2 bsdiff.c -o bsdiff
/tmp/cc7VoH71.o:在函数‘main’中:
bsdiff.c:(.text.startup+0x2aa):对‘BZ2_bzWriteOpen’未定义的引用
bsdiff.c:(.text.startup+0xcfa):对‘BZ2_bzWrite’未定义的引用
bsdiff.c:(.text.startup+0xe37):对‘BZ2_bzWrite’未定义的引用
bsdiff.c:(.text.startup+0xf80):对‘BZ2_bzWrite’未定义的引用
bsdiff.c:(.text.startup+0xfe1):对‘BZ2_bzWriteClose’未定义的引用
bsdiff.c:(.text.startup+0x1034):对‘BZ2_bzWriteOpen’未定义的引用
bsdiff.c:(.text.startup+0x105c):对‘BZ2_bzWrite’未定义的引用
bsdiff.c:(.text.startup+0x1082):对‘BZ2_bzWriteClose’未定义的引用
bsdiff.c:(.text.startup+0x10d5):对‘BZ2_bzWriteOpen’未定义的引用
bsdiff.c:(.text.startup+0x1100):对‘BZ2_bzWrite’未定义的引用
bsdiff.c:(.text.startup+0x1126):对‘BZ2_bzWriteClose’未定义的引用
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'bsdiff' failed
make: *** [bsdiff] Error 1
五、引起错误的原因是因为没有引用bzip2。先进入到bzip2-1.0.6目录下执行make命令:
$ make
If compilation produces errors, or a large number of warnings,
please read README.COMPILATION.PROBLEMS -- you might be able to
adjust the flags in this Makefile to improve matters.
Also in README.COMPILATION.PROBLEMS are some hints that may help
if your build produces an executable which is unable to correctly
handle so-called 'large files' -- files of size 2GB or more.
gcc -Wall -Winline -O2 -g -D_FILE_OFFSET_BITS=64 -c blocksort.c
gcc -Wall -Winline -O2 -g -D_FILE_OFFSET_BITS=64 -c huffman.c
gcc -Wall -Winline -O2 -g -D_FILE_OFFSET_BITS=64 -c crctable.c
gcc -Wall -Winline -O2 -g -D_FILE_OFFSET_BITS=64 -c randtable.c
gcc -Wall -Winline -O2 -g -D_FILE_OFFSET_BITS=64 -c compress.c
gcc -Wall -Winline -O2 -g -D_FILE_OFFSET_BITS=64 -c decompress.c
gcc -Wall -Winline -O2 -g -D_FILE_OFFSET_BITS=64 -c bzlib.c
rm -f libbz2.a
ar cq libbz2.a blocksort.o huffman.o crctable.o randtable.o compress.o decompress.o bzlib.o
ranlib libbz2.a
......
六、编译好bzip2源码后,将整个bzip2目录复制到bsdiff目录下,修改bsdiff.c和bspatch.c的源码
/** bsdiff.c*/
#include <sys/types.h>
#include <bzlib.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/** 导入bzip2的引用*/
#include "bzip2/bzlib.c"
#include "bzip2/crctable.c"
#include "bzip2/compress.c"
#include "bzip2/decompress.c"
#include "bzip2/randtable.c"
#include "bzip2/blocksort.c"
#include "bzip2/huffman.c"
#define MIN(x,y) (((x)<(y)) ? (x) : (y))
......
/** bspatch.c*/
#include <bzlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <err.h>
#include <unistd.h>
#include <fcntl.h>
/** 导入bzip2的引用*/
#include "bzip2/bzlib.c"
#include "bzip2/crctable.c"
#include "bzip2/compress.c"
#include "bzip2/decompress.c"
#include "bzip2/randtable.c"
#include "bzip2/blocksort.c"
#include "bzip2/huffman.c"
......
七、再次切到bsdiff目录下执行make命令
$ make
cc -O3 -lbz2 bsdiff.c -o bsdiff
cc -O3 -lbz2 bspatch.c -o bspatch
八、大功告成,bsdiff在Ubuntu下编译成功,看一下最终目录结构,生成了两个可执行的文件
九、运行bsdiff和bspatch命令检测是否成功。
$ ./bsdiff
bsdiff: usage: ./bsdiff oldfile newfile patchfile
$ ./bspatch
bspatch: usage: ./bspatch oldfile newfile patchfile
十、不想动手编译,想快速使用的同学可以点击这个链接下载bsdiff 4.3,使用Mac的同学也可以使用。