Linux/macOS 上默认兼容 7-Zip v23.01 及以上的 7z.so,用 p7zip 或旧版需加 -DBIT7Z_USE_LEGACY_IUNKNOWN=ON 或指定 -DBIT7Z_7ZIP_VERSION="22.01";运行时使用的 7-Zip 共享库版本最好与构建时一致;Windows 下默认 std::string 按系统代码页处理,非 ASCII 路径需自行保证 UTF-8 或启用 BIT7Z_USE_NATIVE_STRING。
bit7z
rikyozMPL-2.0活跃维护把 7-zip 的压缩解压能力封装成简洁的 C++ 静态库接口,省去直接调用 7-zip 动态库的麻烦,支持多种压缩格式和加密压缩包。
A C++ static library offering a clean and simple interface to the 7-zip shared libraries.
git clone https://github.com/rikyoz/bit7z.git
cmake -S bit7z -B build
cmake --build buildREADME 未说明;仅需支持 x86、x64、arm、arm64 架构的 Windows、Linux、macOS 或 BSD 平台,无 GPU 或显存要求。
跨平台 C++ 静态库,用简洁接口封装 7-Zip 动态库,做压缩解压
把 7-zip 的压缩解压能力封装成简洁的 C++ 静态库接口,省去直接调用 7-zip 动态库的麻烦,支持多种压缩格式和加密压缩包。
核心能力
- 封装 7-Zip 动态库,提供简洁 C++ 接口
- 支持文件系统与内存的压缩解压
- 可读取归档元数据并更新已有归档
- 跨平台支持 Windows、Linux、macOS、BSD
- CMake 配置时自动下载对应版本 7-Zip
容易踩的坑
- v4.1.0Bit7z v4.1.0最新正式版2026-06-17 · 2026-06-17 20:54 UTC
Main Features and Improvements
-
Nested archives support: the new
BitNestedArchiveReaderclass lets you open and inspect archives that are embedded as items inside another archive, without extracting them to disk first. (#92)// Extract the .tar inside a .tar.gz without writing it to disk Bit7zLibrary lib{ "7z.dll" }; BitArchiveReader gz{ lib, "archive.tar.gz", BitFormat::GZip }; BitNestedArchiveReader tar{ lib, gz, BitFormat::Tar }; tar.extractTo( "output/" ); -
Native file I/O: file streams have been rewritten to use low-level Win32 APIs on Windows and POSIX I/O on Unix, replacing
std::fstream. This dramatically improves the performance of both extraction and compression operations. (#319, #325)Due to the choice of using
std::fstreamfor cross-platform support, v4.0 introduced a severe performance regression.For a quick comparison, I did some non-exhaustive benchmarks. The result is the following boxplot, which showcases the scale of that regression and how v4.1 resolves it. In this test, v4.0 extraction takes roughly six times as long as v3, while v4.1 brings it back down into the same range as v3:
Zooming in on just v3 and v4.1 (the v4.0 box is omitted here), a small performance gap remains:
Part of this residual gap is likely due to v4.1 performing additional security validation that v3 did not, so I anticipate a modest, permanent cost relative to v3 in exchange for safer behavior. I'll continue working to reduce, and where possible eliminate, the non-essential portion of this gap in the stable release.
Each version was benchmarked by repeatedly extracting the same archive to the same destination, discarding warmup iterations. Boxes show the median (line) and interquartile range; the cross marks the mean; whiskers follow the Tukey 1.5×IQR convention. Measurements were collected on a single machine; absolute timings are environment-dependent and intended for relative comparison between versions, not as absolute throughput figures. The v4.0 regression and its resolution in v4.1 are large effects that are robust to measurement noise; the finer v3-vs-v4.1 gap is smaller and more sensitive to measurement conditions, so it should be read as indicative rather than exact.
-
New extraction callbacks:
RenameCallback(dynamically rename or skip items during extraction, #123),RawDataCallback(stream raw bytes directly to user code without touching the filesystem, #122), andBufferCallback(route each extracted file to a separate, independently chosen buffer) unlock extraction patterns that were previously impossible.BitFileExtractor extractor{ lib, BitFormat::Zip }; // RenameCallback: skip .tmp files, extract everything else under a subfolder extractor.extract( "archive.zip", "output/", []( uint32_t, const tstring& path ) -> tstring { if ( path.find( ".tmp" ) != tstring::npos ) { return {}; // empty string = skip this item } return "backup/" + path; } ); // RawDataCallback: receive a file's raw bytes without writing to disk std::vector<byte_t> rawData; extractor.extractTo( "archive.zip", [&]( const byte_t* data, std::size_t size ) -> bool { rawData.insert( rawData.end(), data, data + size ); return true; // return false to abort }, /* i
-
- v4.1.0-betaBit7z v4.1.0 Betapre-release2026-05-18 · 2026-05-18 21:31 UTC
查看更新说明
Main Features and Improvements
-
Nested archives support: the new
BitNestedArchiveReaderclass lets you open and inspect archives that are embedded as items inside another archive, without extracting them to disk first. (#92)// Extract the .tar inside a .tar.gz without writing it to disk Bit7zLibrary lib{ "7z.dll" }; BitArchiveReader gz{ lib, "archive.tar.gz", BitFormat::GZip }; BitNestedArchiveReader tar{ lib, gz, BitFormat::Tar }; tar.extractTo( "output/" ); -
Native file I/O: file streams have been rewritten to use low-level Win32 APIs on Windows and POSIX I/O on Unix, replacing
std::fstream. This dramatically improves the performance of both extraction and compression operations. (#319, #325)Due to the choice of using
std::fstreamfor cross-platform support, v4.0 introduced a severe performance regression.For a quick comparison, I did some non-exhaustive benchmarks. The result is the following boxplot, which showcases the scale of that regression and how v4.1 resolves it. In this test, v4.0 extraction takes roughly six times as long as v3, while v4.1 brings it back down into the same range as v3:
Zooming in on just v3 and v4.1 (the v4.0 box is omitted here), a small performance gap remains:
Part of this residual gap is likely due to v4.1 performing additional security validation that v3 did not, so I anticipate a modest, permanent cost relative to v3 in exchange for safer behavior. I'll continue working to reduce, and where possible eliminate, the non-essential portion of this gap in the stable release.
Each version was benchmarked by repeatedly extracting the same archive to the same destination, discarding warmup iterations. Boxes show the median (line) and interquartile range; the cross marks the mean; whiskers follow the Tukey 1.5×IQR convention. Measurements were collected on a single machine; absolute timings are environment-dependent and intended for relative comparison between versions, not as absolute throughput figures. The v4.0 regression and its resolution in v4.1 are large effects that are robust to measurement noise; the finer v3-vs-v4.1 gap is smaller and more sensitive to measurement conditions, so it should be read as indicative rather than exact.
-
New extraction callbacks:
RenameCallback(dynamically rename or skip items during extraction),RawDataCallback(stream raw bytes directly to user code without touching the filesystem), andBufferCallback(route each extracted file to a separate, independently chosen buffer) unlock extraction patterns that were previously impossible.BitFileExtractor extractor{ lib, BitFormat::Zip }; // RenameCallback: skip .tmp files, extract everything else under a subfolder extractor.extract( "archive.zip", "output/", []( uint32_t, const tstring& path ) -> tstring { if ( path.find( ".tmp" ) != tstring::npos ) { return {}; // empty string = skip this item } return "backup/" + path; } ); // RawDataCallback: receive a file's raw bytes without writing to disk std::vector<byte_t> rawData; extractor.extractTo( "archive.zip", [&]( const byte_t* data, std::size_t size ) -> bool { rawData.insert( rawData.end(), data, data + size ); return true; // return false to abort }, /* index = */ 0 ); // Buf
-
- v4.0.12Bit7z v4.0.122026-05-15 · 2026-05-15 17:25 UTC
查看更新说明
⚠️ Security Update ⚠️
This security bugfix release fixes two CVEs reported by @Smarttfoxx:
CVE-2026-45380: An error in how bit7z restored symbolic links from archives allowed an attacker to craft an archive that, when extracted with bit7z on any non-Windows platform, could create a symlink escaping the intended output directory to at most the parent of the output directory. Subsequent archive entries extracted through this symlink would write arbitrary files to the parent of the extraction directory with the permissions of the extracting process.
[!NOTE] Windows is not affected: symbolic link restoration is not supported on this platform, at least for now. On POSIX platforms, the traversal is bounded: an attacker can escape the extraction directory by at most one level.
CVE-2026-45384: When updating an archive, bit7z uses a temporary file with a predictable name (i.e.,
<archive_path>.tmp). This allowed an attacker with write access to the archive directory to pre-place a symlink with the same path as the temporary file but pointing to an arbitrary target file. When a process subsequently updates the archive, the library follows the symlink and overwrites the target with archive data.[!NOTE] Successfully exploiting this vulnerability requires the attacker to already have write access to the directory containing the archive, which significantly limits the attack surface in practice. Also, on Windows creating symbolic links (reparse points) usually requires admin privileges or Dev Mode to be enabled.
Updating to v4.0.12 is strongly recommended; sorry for the inconvenience.
Thanks to @Smarttfoxx for reporting these issues.
Changes from v4.0.11
- Fixed CVE-2026-45380:
- Newline characters within symlink target paths are now treated as valid, as they are on POSIX.
- Embedded null characters in path strings are now correctly handled:
- With
BIT7Z_PATH_SANITIZATION=OFF, null characters are rejected and an exception is thrown. - With
BIT7Z_PATH_SANITIZATION=ON, null characters are replaced with_, consistently with how invalid characters are handled on Windows.
- With
- Symlinks are now recreated with a target relative to the symlink's own parent directory, matching how the OS resolves them at runtime; the target is still validated to ensure it stays within the extraction output directory.
- Fixed CVE-2026-45384:
- When updating an archive in-place:
- On POSIX, instead of opening
<archive>.tmpdirectly, we first create a private temporary directory viamkdtemp(randomized suffix, 0700 permissions) and write the new archive as<tempdir>/data. Because the directory name is unpredictable and inaccessible to other users, an attacker with write access to the archive directory cannot pre-place a symlink at the temp file path. - On Windows, where
mkdtempis unavailable and creating symlinks usually require elevated privileges, the same predictable.tmpextension is kept but the file is opened without createAlways, so an already-existing file or symlink at that path causes afile_existserror and a retry with a numeric postfix (.tmp1,.tmp2, …, up to65535attempts; same behavior as 7-Zip). - In both cases,
CFileOutStreamnow checks existence viafs::symlink_statusrather thanfs::exists, so dangling symlinks are also detected.
- On POSIX, instead of opening
- When updating an archive in-place:
Other changes
- Improved error messages:
- Output archive paths without a filename component are rejected early with a clear error.
- Updating a multi-volume archive now fails explicitly instead of silently creating a single-volume archive.
- Refined and optimized path sanitization
- Fixed CVE-2026-45380:
- v4.0.11Bit7z v4.0.112026-02-24 · 2026-02-24 21:34 UTC
查看更新说明
⚠️ Security Update ⚠️
This security bugfix release fixes CVE-2026-27117.
A path traversal vulnerability ("Zip Slip") existed in bit7z's archive extraction functionality in v4.0.10 and earlier.
The library didn't adequately validate file paths contained in archive entries and returned by 7-Zip's DLLs, which do not perform any validation on entry paths within archives.
This allowed files to be written outside the intended extraction directory through three distinct mechanisms: relative, absolute, and symbolic link path traversal.
Updating to v4.0.11 is strongly recommended; sorry for the inconvenience.
[!NOTE]
The vulnerability only poses a risk if the application using bit7z handles user-supplied/unverified archives.
Changes from v4.0.10
The build option
BIT7Z_PATH_SANITIZATIONis now available on all platforms (previously, it was a Windows-only option).When
BIT7Z_PATH_SANITIZATIONisOFF(the default):- Archive entries with absolute paths (e.g.,
/etc/crontabon Unix systems orC:\Windows\System32\evil.dllon Windows) are rejected, resulting in an extraction failure. - On Windows, entries with drive-relative paths having the same drive root as the output directory are stripped of the drive root (e.g.,
C:file.txt->file.txt), and treated as relative paths; if the drive roots are different, the entry is rejected.
When
BIT7Z_PATH_SANITIZATIONisON:- On Windows:
- Entries with drive-relative paths will be sanitized without creating a dummy directory as in previous versions (e.g.,
C:file.txt->C_file.txtinstead ofC_\file.txt). - Other kinds of paths will be sanitized as in the previous versions (absolute paths are converted to relative paths, e.g.,
C:\Windows\notepad.exe->C_\Windows\notepad.exe).
- Entries with drive-relative paths will be sanitized without creating a dummy directory as in previous versions (e.g.,
- On Linux, entries with absolute paths are stripped of the root path separator prefix, converting them to relative paths (e.g.,
/etc/crontab->etc/crontab).
Regardless of the
BIT7Z_PATH_SANITIZATIONsetting:- Entries with relative paths are rejected if their resolved path falls outside the output directory of the extraction operation (e.g.,
../evil.txt), resulting in an extraction failure. - The target path of symbolic link entries is sanitized in the same way as any other entry path and rejected if it points outside the output directory.
Other changes
- Added support for new archive formats (issue #311):
APFS,AVB,LVM,LP,Sparse - Improved format detection of
VHD/VHDXarchives. - Fixed missing read-only attribute after extracting Tar archives on Windows.
- Fixed and improved reading symbolic links for storing them in archives (https://github.com/rikyoz/bit7z/issues/198#issuecomment-2415681020).
- Fixed automatically adding long paths prefix for long UNC paths.
- Fixed missing namespace scope when using some GUIDs.
- Fixed and updated CMake project version.
- Fixed compile options for MSVC Clang compatibility (issue #322).
Full Changelog: https://github.com/rikyoz/bit7z/compare/v4.0.10...v4.0.11
This is a maintenance release. For a full changelog of the other changes introduced by bit7z v4, please check https://github.com/rikyoz/bit7z/releases/tag/v4.0.0.
Binaries built using the default options with Clang10, GCC 9, MinGW 8, MSVC 2015, 2017, 2019, and 2022 👇
- Archive entries with absolute paths (e.g.,
- v4.0.10Bit7z v4.0.102025-04-12 · 2025-04-12 19:48 UTC
查看更新说明
Changes from v4.0.9
- Added support for disabling format detection via file extension (workaround for #277).
- Now compiling the library with the options
-DBIT7Z_AUTO_FORMAT=ON -DBIT7Z_DETECT_FROM_EXTENSION=OFFwill make it only use file signatures for format detection.
- Now compiling the library with the options
- Added support for Zstd archive format.
- Fixed getting last error code on old versions of MSVC.
- Fixed and improved path sanitization (close issue #268).
- Fixed int8_t storage in BitPropVariant on Arm architectures.
- Fixed arm alignment compiler errors (by @petermarko in https://github.com/rikyoz/bit7z/pull/286).
- Allowed specifying path to 7z library in tests (by @petermarko in https://github.com/rikyoz/bit7z/pull/288).
- Use the
BIT7Z_TESTS_7Z_LIBRARY_PATHbuild option to set the path to 7-Zip shared library to be used for running the tests of bit7z.
- Use the
- Allowed running tests on target when cross-compiling (by @petermarko in https://github.com/rikyoz/bit7z/pull/289).
- Fixed BitArchiveReader's isMultiVolume() and volumesCount() (close issue #291).
- Now these methods will take into account when a multi-volume archive is opened with the whole archive format rather than
BitFormat::Split, and they will report the correct result.
- Now these methods will take into account when a multi-volume archive is opened with the whole archive format rather than
- Fixed tests with musl (by @petermarko in https://github.com/rikyoz/bit7z/pull/292).
New Contributors
- @petermarko made their first contribution in https://github.com/rikyoz/bit7z/pull/286
Full Changelog: https://github.com/rikyoz/bit7z/compare/v4.0.9...v4.0.10
This is a maintenance release. For a full changelog of the other changes introduced by bit7z v4, please check https://github.com/rikyoz/bit7z/releases/tag/v4.0.0.
Binaries built using the default options with Clang10, GCC 9, MinGW 8, MSVC 2015, 2017, 2019, and 2022 👇
- Added support for disabling format detection via file extension (workaround for #277).
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
⚡️ Introduction
bit7z is a cross-platform C++ static library that allows the compression/extraction of archive files through a clean and simple wrapper interface to the dynamic libraries from the 7-Zip project. It supports compression and extraction to and from the filesystem or the memory, reading archives metadata, updating existing ones, creating multi-volume archives, operation progress callbacks, and many other functionalities.
🎯 Supported Features
- Compression using the following archive formats: 7z, XZ, BZIP2, GZIP, TAR, ZIP, and WIM.
- Extraction of many archive formats: 7z, AR, ARJ, BZIP2, CAB, CHM, CPIO, CramFS, DEB, DMG, EXT, FAT, GPT, GZIP, HFS, HXS, IHEX, ISO, LZH, LZMA, MBR, MSI, NSIS, NTFS, QCOW2, RAR, RAR5, RPM, SquashFS, TAR, UDF, UEFI, VDI, VHD, VMDK, WIM, XAR, XZ, Z, and ZIP.
- Reading metadata of archives and their content.
- Testing archives for errors.
- Updating existing file archives with new files.
- Renaming, updating, or deleting old items in existing file archives.
- Compression and extraction to and from memory and C++ standard streams.
- Compression using custom path aliases for the items in the output archives.
- Selective extraction of only specified files/folders using wildcards and regular expressions.
- Selective extraction of folders, and extraction of an archive's root folder content.
- Renaming the extracted items via a callback.
- Reading raw extracted data through a callback.
- Reading and extracting nested and sub-archives without writing the intermediate files.
- Creation of encrypted archives (strong AES-256 encryption; only for 7z and ZIP formats).
- Archive header encryption (only for 7z format).
- Possibility to choose the compression level (if supported by the archive format), the compression method (supported methods), the dictionary size, and the word size.
- Automatic input archive format detection.
- Opening self-extracting (SFX) archives and executables with appended data.
- Deferred loading of the 7-Zip shared library.
- Solid archives (only for 7z).
- Multi-volume archives.
- Operation callbacks for obtaining real-time information about ongoing operations.
- Canceling or pausing the current operation.
[!NOTE]
The presence or not of some of the above features depends on the specific 7-Zip shared library used.
For example, 7z.dll should support all these features, 7za.dll should work only with the 7z file format, and 7zxa.dll can only extract 7z files.
For more information about the 7-Zip DLLs, please check this wiki page.
[!NOTE]
Some features (e.g., automatic format detection and selective extraction using regular expressions) are disabled by default, and macro definitions must be used during compilation to have them available (wiki).
🔥 Getting Started (Library Usage)
Below are a few examples that show how to use some of the main features of bit7z.
📂 Extracting Files from an Archive
#include <bit7z/bitfileextractor.hpp>
try { // bit7z classes can throw BitException objects
using namespace bit7z;
Bit7zLibrary lib{ "7za.dll" };
BitFileExtractor extractor{ lib, BitFormat::SevenZip };
// Extracting a simple archive
extractor.extract( "path/to/archive.7z", "out/dir/" );
// Extracting a specific file inside an archive
extractor.extractMatching( "path/to/archive.7z", "file.pdf", "out/dir/" );
// Extracting the first file of an archive to a buffer
std::vector< byte_t > buffer;
extractor.extract( "path/to/archive.7z", buffer );
// Extracting an encrypted archive
extractor.setPassword( "password" );
extractor.extract( "path/to/another/archive.7z", "out/dir/" );
} catch ( const bit7z::BitException& ex ) { /* Do something with ex.what()...*/ }
Alternatively, if you only need to work on a single archive:
#include <bit7z/bitarchivereader.hpp>
try { // bit7z classes can throw BitException objects
using namespace bit7z;
Bit7zLibrary lib{ "7z.dll" };
// Opening the archive
BitArchiveReader archive{ lib, "path/to/archive.gz", BitFormat::GZip };
// Testing the archive
archive.test();
// Extracting the archive
archive.extractTo( "out/dir/" );
} catch ( const bit7z::BitException& ex ) { /* Do something with ex.what()...*/ }
💼 Compressing Files into an Archive
#include <bit7z/bitfilecompressor.hpp>
try { // bit7z classes can throw BitException objects
using namespace bit7z;
Bit7zLibrary lib{ "7z.dll" };
BitFileCompressor compressor{ lib, BitFormat::Zip };
std::vector< std::string > files = { "path/to/file1.jpg", "path/to/file2.pdf" };
// Creating a simple zip archive
compressor.compress( files, "output_archive.zip" );
// Creating a zip archive with a custom directory structure
std::map< std::string, std::string > files_map = {
{ "path/to/file1.jpg", "alias/path/file1.jpg" },
{ "path/to/file2.pdf", "alias/path/file2.pdf" }
};
compressor.compress( files_map, "output_archive2.zip" );
// Compressing a directory
compressor.compressDirectory( "dir/path/", "dir_archive.zip" );
// Creating an encrypted zip archive of two files
compressor.setPassword( "password" );
compressor.compressFiles( files, "protected_archive.zip" );
// Updating an existing zip archive
compressor.setUpdateMode( UpdateMode::Append );
compressor.compressFiles( files, "existing_archive.zip" );
// Compressing a single file into a buffer
std::vector< bit7z::byte_t > buffer;
BitFileCompressor compressor2{ lib, BitFormat::BZip2 };
compressor2.compressFile( files[0], buffer );
} catch ( const bit7z::BitException& ex ) { /* Do something with ex.what()...*/ }
Alternatively, if you only need to work on a single archive:
#include <bit7z/bitarchivewriter.hpp>
try { // bit7z classes can throw BitException objects
using namespace bit7z;
Bit7zLibrary lib{ "7z.dll" };
BitArchiveWriter archive{ lib, BitFormat::SevenZip };
// Adding the items to be compressed (no compression is performed here)
archive.addFile( "path/to/file.txt" );
archive.addDirectory( "path/to/dir/" );
// Compressing the added items to the output archive
archive.compressTo( "output.7z" );
} catch ( const bit7z::BitException& ex ) { /* Do something with ex.what()...*/ }
📑 Reading Archive Metadata
#include <bit7z/bitarchivereader.hpp>
try { // bit7z classes can throw BitException objects
using namespace bit7z;
Bit7zLibrary lib{ "7za.dll" };
BitArchiveReader arc{ lib, "archive.7z", BitFormat::SevenZip };
// Printing archive metadata
std::cout << "Archive properties\n";
std::cout << " Items count: " << arc.itemsCount() << '\n';
std::cout << " Folders count: " << arc.foldersCount() << '\n';
std::cout << " Files count: " << arc.filesCount() << '\n';
std::cout << " Size: " << arc.size() <<'\n';
std::cout << " Packed size: " << arc.packSize() << "\n\n";
// Printing the metadata of the archived items
std::cout << "Archived items";
for ( const auto& item : arc ) {
std::cout << '\n';
std::cout << " Item index: " << item.index() << '\n';
std::cout << " Name: " << item.name() << '\n';
std::cout << " Extension: " << item.extension() << '\n';
std::cout << " Path: " << item.path() << '\n';
std::cout << " IsDir: " << item.isDir() << '\n';
std::cout << " Size: " << item.size() << '\n';
std::cout << " Packed size: " << item.packSize() << '\n';
std::cout << " CRC: " << std::hex << item.crc() << std::dec << '\n';
}
std::cout.flush();
} catch ( const bit7z::BitException& ex ) { /* Do something with ex.what()...*/ }
A complete API reference is available in the wiki section.
🚀 Upgrading from bit7z v3 to v4
The newest bit7z v4 introduced some significant breaking changes to the library's API.
- By default, the project now follows the UTF-8 Everywhere Manifesto:
- The default string type is
std::string(instead ofstd::wstring), so users can use the library in cross-platform projects more easily (v4 introduced Linux/macOS support too). - Input
std::strings will be considered as UTF-8 encoded. - You can still achieve the old behavior on Windows using the
-DBIT7Z_USE_NATIVE_STRINGCMake option.
- The default string type is
- The old
BitExtractorclass is now calledBitFileExtractor.- Now
BitExtractoris just the name of a template class for all the extraction classes.
- Now
- The old
BitCompressorclass is now calledBitFileCompressor.- Now
BitCompressoris just the name of a template class for all the compression classes.
- Now
- The old
BitArchiveInfoclass is now calledBitArchiveReader, and it allows to extract single archives. - The
ProgressCallbacknow must return aboolvalue indicating whether the current operation can continue (true) or not (false). - The
BitExceptionclass now inherits fromstd::system_errorrather thanstd::runtime_error.- The method
BitException::getErrorCode()was renamedBitException::hresultCode().
- The method
- The project structure changed:
- Public API headers moved from
include/to theinclude/bit7z/folder, so#includedirectives now need to prependbit7z/to the included header name (e.g.,#include <bit7z/bitfileextractor.hpp>).- Even though it is a bit verbose, it is a typical structure for C and C++ libraries, and it makes explicit which third-party library a header file belongs to.
- By default, the output folder of bit7z is now
lib/<architecture>/; if the CMake generator is multi-config (e.g., Visual Studio generators), the default output folder islib/<architecture>/<build type>/.- Optionally, you can force using the "Visual Studio style" output path by enabling the
BIT7Z_VS_LIBNAME_OUTDIR_STYLECMake option.
- Optionally, you can force using the "Visual Studio style" output path by enabling the
- Third-party dependencies are no longer handled using git submodules but are automatically downloaded using CPM.cmake when configuring/using the library via CMake.
- Public API headers moved from
💾 Download
Each released package contains:
- A pre-compiled version of bit7z (both in debug and release mode);
- The public API headers needed to use the library in your program;
Packages are available for both x86 and x64 architectures.
You can also clone/download this repository and build the library yourself (please, read the wiki).
🧰 Requirements
- Operating System: Windows, Linux, macOS, Android.
- Architecture: x86, x86_64, arm, arm64.
- Language Standard: C++11 (for using the library), C++14 (for building the library).
- Compiler: MSVC 2015 or later1, MinGW v6.4 or later, GCC v4.9 or later, Clang 3.6 or later.
- Shared Library: a 7-Zip
.dlllibrary on Windows, a 7-Zip/p7zip.solibrary on Unix.
[!NOTE]
- RAR Archive Support: The library supports RAR archives only when using 7-Zip's
7z.dll/7z.so. It doesn't support p7zip's unrar plugin. For RAR extraction on Unix-based systems, you need to build the 7-Zip7z.solibrary.- 7-Zip Libraries: Bit7z does not ship with the 7-Zip shared libraries. You can download the precompiled binaries or build them from the source at 7-zip.org.
🔗 Installation
The library can be installed as a dependency of your project in a number of different ways:
Using CMake's add_subdirectory
You can directly integrate the library into your CMake project:
- Either download bit7z's sources to a sub-directory of your project (e.g.,
third_party), or add this repository as a git submodule of yours. - Then, use the command
add_subdirectory()in yourCMakeLists.txtto include bit7z. - Finally, link the
bit7zlibrary using thetarget_link_libraries()command.
For example:
add_subdirectory(${CMAKE_SOURCE_DIR}/third_party/bit7z) # Path to bit7z's repository
# Here you can enable/disable bit7z's build options, e.g.:
# set(BIT7Z_USE_NATIVE_STRING ON CACHE BOOL "enable using native OS strings" FORCE)
target_link_libraries(${YOUR_TARGET} PRIVATE bit7z)
Using CPM.cmake
CPMAddPackage("gh:rikyoz/bit7z@<version>") # Replace <version> with the desired one.
# Here you can enable/disable bit7z's build options, e.g.:
# set(BIT7Z_AUTO_FORMAT ON CACHE BOOL "enable auto format support" FORCE)
target_link_libraries(${YOUR_TARGET} PRIVATE bit7z)
Using vcpkg
First, you need to install the library:
vcpkg install bit7z
Then, you add bit7z as a dependency in your project's CMakeLists.txt:
find_package(bit7z CONFIG REQUIRED)
target_link_libraries(${YOUR_TARGET} PRIVATE bit7z::bit7z)
Building from source and manually linking
The wiki provides instructions on how to build the library from the source code and manually link it into your project.
🛠️ Configuration
The library is highly customizable: for a detailed list of the available build options, please refer to the wiki.
📌 7-Zip Version
While configuring bit7z via CMake, it automatically downloads the latest version of 7-Zip supported by the library.
Optionally, you can specify a different version of 7-Zip via the CMake option BIT7Z_7ZIP_VERSION (e.g., -DBIT7Z_7ZIP_VERSION="22.01").
Alternatively, you can specify a custom path containing the 7-Zip source code via the option BIT7Z_CUSTOM_7ZIP_PATH.
[!NOTE]
In general, it is best to use the same version of 7-Zip of the shared libraries that you will use at runtime.
Using 7-Zip v23.01 on Linux and macOS
By default, bit7z is compatible with the 7z.so from 7-Zip v23.01 and later.
If you plan to use the 7z.so from p7zip or 7-Zip v22.01 and earlier instead, you have two ways to make bit7z compatible:
- Configure bit7z with the CMake option
-DBIT7Z_USE_LEGACY_IUNKNOWN=ON; or - Configure bit7z for 7-Zip v22.01 (i.e.,
-DBIT7Z_7ZIP_VERSION="22.01").
On Linux and macOS, 7-Zip v23.01 introduced breaking changes to the IUnknown interface. As a result, if you build bit7z for such a version of 7-Zip (the default), it will not support using the shared libraries from previous versions of 7-Zip (or from p7zip). Conversely, bit7z made for earlier versions of 7-Zip or for p7zip is incompatible with the shared libraries from 7-Zip v23.01 and later.
You can build the shared libraries of 7-Zip v23.01 in a backward-compatible mode by defining the macro Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN.
If this is your case, you'll need to enable the BIT7Z_USE_LEGACY_IUNKNOWN to make bit7z work (in this case, bit7z will be compatible also with previous versions of 7-Zip/p7zip).
🗺️ String Encoding
By default, bit7z follows the UTF-8 Everywhere Manifesto to simplify the use of the library within cross-platform projects. In short, this means that:
- The default path string type is
std::string. - Input
std::strings are considered as UTF-8 encoded; outputstd::strings are UTF-8 encoded.
On POSIX systems, std::strings are usually already UTF-8 encoded, and no configuration is needed.
The situation is a bit more complex on Windows since, by default, Windows treats std::strings as encoded using the system code page, which may not necessarily be UTF-8, like, for example, Windows-1252.
If your program deals exclusively with ASCII-only strings, you should be fine with the default bit7z settings (as ASCII characters are also UTF-8).
However, if you need to handle non-ASCII/Unicode characters, as it is likely, you have the following options:
-
Enforcing using the UTF-8 code page for your whole application, as explained by Microsoft here:
- Recommended, but supported only since Windows 10 1903 and later.
-
Manually ensuring the encoding of the
std::strings passed to bit7z:- You can use some string encoding library or C++11's UTF-8 string literals for input strings.
- User-input strings (e.g., the password of an archive) can be handled as explained here; in short: read the input as an UTF-16 wide string (e.g., via
ReadConsoleW), and convert it to UTF-8 (bit7z provides a utility function for this,bit7z::to_tstring). - You can correctly print the UTF-8 output strings from bit7z (e.g., the path/name metadata of a file in an archive) to the console by calling
SetConsoleOutputCP(CP_UTF8)before.
-
Configuring bit7z to use UTF-16 encoded wide strings (i.e.,
std::wstring) by enabling theBIT7Z_USE_NATIVE_STRINGoption via CMake.-
If your program is Windows-only, or you already use wide strings on Windows, this might be the best choice since it will avoid any internal string conversions (7-Zip always uses wide strings).
-
This option makes developing cross-platform applications slightly inconvenient since you'll still have to use
std::stringon POSIX systems. -
The library provides a type alias
bit7z::tstringand a macro functionBIT7Z_STRINGfor defining wide string variables and literals on Windows and narrow ones on other platforms. -
You must programmatically set the standard input and output encoding to UTF-16 to correctly read and print Unicode characters:
#include <fcntl.h> //for _O_U16TEXT #include <io.h> //for _setmode _setmode(_fileno(stdout), _O_U16TEXT); // setting the stdout encoding to UTF16 _setmode(_fileno(stdin), _O_U16TEXT); // setting the stdin encoding to UTF16
-
-
Configuring bit7z to use the system code page encoding for
std::stringby enabling theBIT7Z_USE_SYSTEM_CODEPAGEoption via CMake.- Not recommended: using this option, your program will be limited in the set of characters it can pass to and read from bit7z.
🔍 SAST Tools
PVS-Studio - static analyzer for C, C++, C#, and Java code.
☕️ Donate
If you have found this project helpful, please consider supporting me with a small donation so that I can keep improving it! Thank you! :pray:
📜 License
This project is licensed under the terms of the Mozilla Public License v2.0. For more details, please check:
- The LICENSE file.
- Mozilla's MPL-2.0 FAQ
Older versions (v3.x and earlier) of bit7z were released under the GNU General Public License v2.
Footnotes
-
MSVC 2010 was supported until v2.x, MSVC 2012/2013 until v3.x. ↩