#include <archive.h>报错
archive配置
Linux环境下,在C++项目.cpp文件中存在如下语句,导致无法运行~
#include <archive.h>
#include <archive_entry.h>
由于C++编译器默认不包含archive,所以我们需要自行配置。
Libarchive 3.6.2 安装教程
查看了许多教程,了解到在g++
编译时需要包含archive的静态链接库或者动态链接库。
接下来就是下载libarchive
,进行安装,安装之后会自动生成archive
的静态链接库libarchive.a
。
下载链接如下:
Release Libarchive 3.6.2 · libarchive/libarchive (github.com)
将软件包下载至指定位置解压,之后进入目录libarchive 3.6.2
,执行如下命令安装。
./configure
make
sudo make install
如下图所示,没有报错就是安装成功了!由图中的提示信息,我们了解到安装的目录是/usr/local/lib/
。
然后,我们进入目录,看到安装成功的静态链接库libarchive.a
以及动态链接库libarchive.so.13.6.2
。
编译
如下是gcc的命令行参数说明,g++是同样的道理。
gcc简介和命令行参数说明-CSDN博客
C/C++专题—gcc g++ 参数详解 - 知乎 (zhihu.com)
-static 此选项将禁止使用动态库。
-o 制定输出名称,缺省的时候,gcc 编译出来的文件是a.out
-O0
-O1
-O2
-O3
编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高。
我们首先执行了如下的bash命令。
g++ -O3 /home/fanjiarong/文档/Coverset/test_6.cpp /usr/local/lib/libarchive.a -o /home/fanjiarong/文档/Coverset/test_6
可惜报错如下所示:
fanjiarong@fanjiarong-virtual-machine:~/文档/Coverset$ g++ -O3 /home/fanjiarong/文档/Coverset/test_6.cpp /usr/local/lib/libarchive.a -o /home/fanjiarong/文档/Coverset/test_6
/usr/bin/ld: /tmp/ccd5ARH1.o: in function `main':
crc32.cpp:(.text.startup+0x0): multiple definition of `main'; /tmp/ccVV3AU0.o:test_6.cpp:(.text.startup+0x0): first defined here
/usr/bin/ld: /usr/local/lib/libarchive.a(archive_read_support_filter_gzip.o): in function `gzip_filter_close':
/home/fanjiarong/libarchive-3.6.2/libarchive/archive_read_support_filter_gzip.c:519: undefined reference to `inflateEnd'
/usr/bin/ld: /usr/local/lib/libarchive.a(archive_read_support_filter_gzip.o): in function `consume_header':
/home/fanjiarong/libarchive-3.6.2/libarchive/archive_read_support_filter_gzip.c:350: undefined reference to `crc32'
/usr/bin/ld: /home/fanjiarong/libarchive-3.6.2/libarchive/archive_read_support_filter_gzip.c:356: undefined reference to `inflateInit2_'
/usr/bin/ld: /usr/local/lib/libarchive.a(archive_read_support_filter_gzip.o): in function `gzip_filter_read':
/home/fanjiarong/libarchive-3.6.2/libarchive/archive_read_support_filter_gzip.c:472: undefined reference to `inflate'
/usr/bin/ld: /usr/local/lib/libarchive.a(archive_read_support_filter_gzip.o): in function `consume_trailer':
/home/fanjiarong/libarchive-3.6.2/libarchive/archive_read_support_filter_gzip.c:401: undefined reference to `inflateEnd'
collect2: error: ld returned 1 exit status
之后查阅资料,在如下的博客中找到了解决方案!
undefined reference to inflateInit2_ 解决方案
解决方法是:加上-lz
。
fanjiarong@fanjiarong-virtual-machine:~/文档/Coverset$ g++ -O3 /home/fanjiarong/文档/Coverset/test_6.cpp /usr/local/lib/libarchive.a -o /home/fanjiarong/文档/Coverset/test_6 -lz
到此为止,成功编译,生成test_6
可执行文件。如果运行直接在对应目录下执行./test_6
即可!
archive学习笔记
Linux压缩库 archive 使用
libarchive项目开发了一个可移植、高效的C库,可以读取和写入各种格式的流式归档。
大家可以参照以上博客进行系统学习,本文仅对我学习项目用到的函数进行简单记录,同时可以体现archive具体如何使用:
/* 将 buf 对应的文件解压为archive对象 */
struct archive *open_tgz(void *buf, size_t size)
{
struct archive *a = archive_read_new(); // 分配和初始化适合从存档中读取的struct归档对象
archive_read_support_compression_gzip(a); // 为指定的gzip压缩启用自动检测代码和解压缩支持
archive_read_support_format_tar(a);
assert(archive_read_open_memory(a, buf, size) == ARCHIVE_OK); // ARCHIVE_OK=0 本函数用于打开存档,并准备读取条目 正常情况不会触发assert
return a;
}
size_t size;
unsigned long long *archive_buf = (unsigned long long *)map_file("一个tgz文件路径/output.tgz", size);
struct archive *a = open_tgz(archive_buf, size);
struct archive_entry *entry;
// archive_read_next_header():读取下一个条目的标题,并返回指向struct archive_entry的指针。
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
cout << archive_entry_pathname(entry) << endl;
}