zlib 壓縮庫:編譯安裝指南與步驟教學

到底要怎麼使用 C/C++ 壓縮或解壓縮檔案呢?
那就來看看 zlib 吧 ~
壓縮格式
在 Linux 中常常看到不同的壓縮格式,常見的像是 zip 和 gz,這些到底有甚麼差別?
大部分的 zip 和 gz 都是底層採用 deflate 演算法 (RFC1951) 壓縮,外面再加上不同的封裝
zip 可以將多的檔案放在一起壓縮,副檔名通常為 .zip
但 gz 只能針對單一檔案壓縮,因此 gz 通常都搭配 tar 一起使用,副檔名為 .tar.gz
Zlib
Zlib 就是支援 deflate 演算法的 library,可以透過他來壓縮和解壓縮
其實 zlib 也是一個壓縮格式,底層也是基於 deflate,因此常常與 Zlib library 搞混
Zlib library 由 Jean-loup Gailly and Mark Adler 開發
本身除了支援 deflate 之外,也支援 zlib 格式和 gzip 格式
下面我們就來介紹如何編譯 Zlib library 吧 ~
Build
在開始之前,我們會用到 git 和 cmake,沒有的可以先安裝一下。
下載 zlib libary 的 source code
使用 git 來下載檔案
git clone https://github.com/madler/zlib
$ git clone https://github.com/madler/zlib Cloning into 'zlib'... remote: Enumerating objects: 6117, done. remote: Counting objects: 100% (330/330), done. remote: Compressing objects: 100% (140/140), done. remote: Total 6117 (delta 193), reused 266 (delta 187), pack-reused 5787 Receiving objects: 100% (6117/6117), 4.24 MiB | 1002.00 KiB/s, done. Resolving deltas: 100% (4279/4279), done.
cmake configure
在編譯之前要先產生 Makefile,先進去 zlib 資料夾內,並下指令讓 cmake 產生必要的檔案
我們設定將編譯過程產生的檔案放在
build
,另外設定最後安裝的位置為build/install
這邊使用 MinGW 做示範,因此使用
MinGW Makefiles
,如果不是用 MinGW 的可以使用其他的 Cmake Generatorcd zlib cmake -S . -B build -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=build/install
$ cmake -S . -B build -G "MinGW Makefiles" -- The C compiler identification is GNU 13.1.0 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: C:/MinGW/mingw64/bin/gcc.exe - skipped -- Detecting C compile features -- Detecting C compile features - done -- Looking for sys/types.h -- Looking for sys/types.h - found -- Looking for stdint.h -- Looking for stdint.h - found -- Looking for stddef.h -- Looking for stddef.h - found -- Check size of off64_t -- Check size of off64_t - done -- Looking for fseeko -- Looking for fseeko - found -- Looking for unistd.h -- Looking for unistd.h - found -- Renaming -- D:/zlib/zlib/zconf.h -- to 'zconf.h.included' because this file is included with zlib -- but CMake generates it automatically in the build directory. -- Configuring done (7.6s) -- Generating done (0.2s) -- Build files have been written to: D:/zlib/zlib/build
cmake build
接著就可以開始編譯了,我們設定將編譯產生的檔案放在
build
cmake --build build
$ cmake --build build [ 2%] Generating zlib1rc.obj [ 4%] Building C object CMakeFiles/zlib.dir/adler32.c.obj [ 7%] Building C object CMakeFiles/zlib.dir/compress.c.obj [ 9%] Building C object CMakeFiles/zlib.dir/crc32.c.obj [ 12%] Building C object CMakeFiles/zlib.dir/deflate.c.obj [ 14%] Building C object CMakeFiles/zlib.dir/gzclose.c.obj [ 17%] Building C object CMakeFiles/zlib.dir/gzlib.c.obj [ 19%] Building C object CMakeFiles/zlib.dir/gzread.c.obj [ 21%] Building C object CMakeFiles/zlib.dir/gzwrite.c.obj [ 24%] Building C object CMakeFiles/zlib.dir/inflate.c.obj [ 26%] Building C object CMakeFiles/zlib.dir/infback.c.obj [ 29%] Building C object CMakeFiles/zlib.dir/inftrees.c.obj [ 31%] Building C object CMakeFiles/zlib.dir/inffast.c.obj [ 34%] Building C object CMakeFiles/zlib.dir/trees.c.obj [ 36%] Building C object CMakeFiles/zlib.dir/uncompr.c.obj [ 39%] Building C object CMakeFiles/zlib.dir/zutil.c.obj [ 41%] Linking C shared library libzlib.dll [ 41%] Built target zlib [ 43%] Building C object CMakeFiles/zlibstatic.dir/adler32.c.obj [ 46%] Building C object CMakeFiles/zlibstatic.dir/compress.c.obj [ 48%] Building C object CMakeFiles/zlibstatic.dir/crc32.c.obj [ 51%] Building C object CMakeFiles/zlibstatic.dir/deflate.c.obj [ 53%] Building C object CMakeFiles/zlibstatic.dir/gzclose.c.obj [ 56%] Building C object CMakeFiles/zlibstatic.dir/gzlib.c.obj [ 58%] Building C object CMakeFiles/zlibstatic.dir/gzread.c.obj [ 60%] Building C object CMakeFiles/zlibstatic.dir/gzwrite.c.obj [ 63%] Building C object CMakeFiles/zlibstatic.dir/inflate.c.obj [ 65%] Building C object CMakeFiles/zlibstatic.dir/infback.c.obj [ 68%] Building C object CMakeFiles/zlibstatic.dir/inftrees.c.obj [ 70%] Building C object CMakeFiles/zlibstatic.dir/inffast.c.obj [ 73%] Building C object CMakeFiles/zlibstatic.dir/trees.c.obj [ 75%] Building C object CMakeFiles/zlibstatic.dir/uncompr.c.obj [ 78%] Building C object CMakeFiles/zlibstatic.dir/zutil.c.obj [ 80%] Linking C static library libzlibstatic.a [ 80%] Built target zlibstatic [ 82%] Building C object CMakeFiles/example.dir/test/example.c.obj [ 85%] Linking C executable example.exe [ 85%] Built target example [ 87%] Building C object CMakeFiles/minigzip.dir/test/minigzip.c.obj [ 90%] Linking C executable minigzip.exe [ 90%] Built target minigzip [ 92%] Building C object CMakeFiles/example64.dir/test/example.c.obj [ 95%] Linking C executable example64.exe [ 95%] Built target example64 [ 97%] Building C object CMakeFiles/minigzip64.dir/test/minigzip.c.obj [100%] Linking C executable minigzip64.exe [100%] Built target minigzip64
安裝
最後下指令安裝即可,安裝的位置在先前設定的
build/install
cmake --install build
$ cmake --install build -- Install configuration: "" -- Installing: D:/C/endgame_verify/3dparty/zlib/zlib/build/install/lib/libzlib.dll.a -- Installing: D:/C/endgame_verify/3dparty/zlib/zlib/build/install/bin/libzlib.dll -- Installing: D:/C/endgame_verify/3dparty/zlib/zlib/build/install/lib/libzlibstatic.a -- Installing: D:/C/endgame_verify/3dparty/zlib/zlib/build/install/include/zconf.h -- Installing: D:/C/endgame_verify/3dparty/zlib/zlib/build/install/include/zlib.h -- Installing: D:/C/endgame_verify/3dparty/zlib/zlib/build/install/share/man/man3/zlib.3 -- Installing: D:/C/endgame_verify/3dparty/zlib/zlib/build/install/share/pkgconfig/zlib.pc
範例
這邊稍微用 C++ 寫一下 gzip 格式的壓縮和解壓縮
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include "zlib/zlib.h"
decompress(const std::string &inFileName, const std::string &outFileName)
{
gzFile infile = gzopen(inFileName.data(), "rb");
std::ofstream outfile(outFileName, std::ios::binary | std::ios::out);
if (!infile || !outfile)
{
return -1;
}
char buf[128];
int num_read = 0;
while ((num_read = gzread(infile, buf, sizeof(buf))) > 0)
{
outfile.write(buf, num_read);
}
gzclose(infile);
outfile.close();
return 0;
}
int compress(const std::string &inFileName, const std::string &outFileName)
{
std::ifstream infile(inFileName, std::ios::binary | std::ios::in);
gzFile outfile = gzopen(outFileName.data(), "wb");
if (!infile || !outfile)
{
return -1;
}
char buf[128];
while (true)
{
infile.read(buf, sizeof(buf));
int num_read = infile.gcount();
if (num_read == 0)
{
break;
}
gzwrite(outfile, buf, num_read);
}
infile.close();
gzclose(outfile);
return 0;
}
int main(int argc, char **argv)
{
if (argc < 3)
{
std::cerr << argv[0] << " <C/D> <source> <output>" << std::endl;
exit(EXIT_FAILURE);
}
if (argv[1][0] == 'C')
{
if (compress(std::string(argv[2]), std::string(argv[3])) == -1)
{
std::cerr << "Error" << std::endl;
exit(EXIT_FAILURE);
}
}
else if (argv[1][0] == 'D')
{
if (decompress(std::string(argv[2]), std::string(argv[3])) == -1)
{
std::cerr << "Error" << std::endl;
exit(EXIT_FAILURE);
}
}
std::cout << "Done" << std::endl;
}
編譯時候記得設定 link 和 header 的路徑,然後 link zlib
因為是用 shared library,記得把 dll 複製過來
dll 位置在 build/install/bin/libzlib.dll
g++ test.cpp -o test.exe -l zlib -L zlib/build/install/lib -I zlib/build/install/include
附上用 static 的編譯指令:
g++ -static test.cpp -o test.exe -l zlibstatic -L zlib/build/install/lib -I zlib/build/install/include
Reference
如果你覺得這篇文章有用 可以考慮贊助飲料給大貓咪