diff --git a/.docker/build-linux.sh b/.docker/build-linux.sh index 8ed9e63d..542966c7 100755 --- a/.docker/build-linux.sh +++ b/.docker/build-linux.sh @@ -171,6 +171,7 @@ case "-$BUILD_TYPE-" in *-minimal-*) CMAKE_ARGS="${CMAKE_ARGS} -DENABLE_PERFMON=0 -DWITH_MAN_OPTION=0 -DENABLE_RICEPP=0" CMAKE_ARGS="${CMAKE_ARGS} -DTRY_ENABLE_BROTLI=0 -DTRY_ENABLE_LZ4=0 -DTRY_ENABLE_FLAC=0" + CMAKE_ARGS="${CMAKE_ARGS} -DDWARFSEXTRACT_MINIMAL=1 -DDISABLE_FILESYSTEM_EXTRACTOR_FORMAT=1" ;; esac diff --git a/CMakeLists.txt b/CMakeLists.txt index 894b7445..d891d09d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,8 @@ option(WITH_FUSE_EXTRACT_BINARY "build with fuse-extract binary" OFF) option(WITH_PXATTR "build with pxattr binary" OFF) option(WITH_EXAMPLE "build with example binary" OFF) option(ENABLE_STACKTRACE "build with stack trace support" OFF) +option(DWARFSEXTRACT_MINIMAL "disable patterns support in dwarfsextract" OFF) +option(DISABLE_FILESYSTEM_EXTRACTOR_FORMAT "disable filesystem extractor format support" OFF) if(APPLE) option(USE_HOMEBREW_LIBARCHIVE "use libarchive from homebrew" ON) endif() @@ -265,6 +267,7 @@ if(WITH_LIBDWARFS) set(DWARFS_BUILTIN_MANPAGE ${WITH_MAN_OPTION}) set(DWARFS_PERFMON_ENABLED ${ENABLE_PERFMON}) set(DWARFS_STACKTRACE_ENABLED ${ENABLE_STACKTRACE}) + set(DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT ${DISABLE_FILESYSTEM_EXTRACTOR_FORMAT}) configure_file(cmake/config.h.in include/dwarfs/config.h @ONLY) else() @@ -297,6 +300,9 @@ if(WITH_TOOLS) target_link_libraries(mkdwarfs_main PRIVATE dwarfs_reader dwarfs_writer dwarfs_rewrite) target_link_libraries(dwarfsck_main PRIVATE dwarfs_reader) target_link_libraries(dwarfsextract_main PRIVATE dwarfs_extractor) + target_compile_definitions(dwarfsextract_main PRIVATE + $<$:DWARFSEXTRACT_MINIMAL> + ) if(WITH_UNIVERSAL_BINARY) add_executable(dwarfsuniversal tools/src/universal.cpp) @@ -576,6 +582,9 @@ if(WITH_TESTS) if(TARGET tool_main_test) target_link_libraries(tool_main_test PRIVATE mkdwarfs_main dwarfsck_main dwarfsextract_main PkgConfig::LIBARCHIVE) + target_compile_definitions(tool_main_test PRIVATE + $<$:DWARFSEXTRACT_MINIMAL> + ) endif() if(TARGET manpage_test) @@ -587,6 +596,9 @@ if(WITH_TESTS) target_compile_definitions(manpage_test PRIVATE DWARFS_WITH_FUSE_DRIVER) target_link_libraries(manpage_test PRIVATE dwarfs_main) endif() + target_compile_definitions(manpage_test PRIVATE + $<$:DWARFSEXTRACT_MINIMAL> + ) endif() if(TARGET tools_test) diff --git a/cmake/config.h.in b/cmake/config.h.in index 56b69074..c0913342 100644 --- a/cmake/config.h.in +++ b/cmake/config.h.in @@ -11,4 +11,5 @@ #cmakedefine DWARFS_BUILTIN_MANPAGE 1 #cmakedefine DWARFS_PERFMON_ENABLED 1 #cmakedefine DWARFS_STACKTRACE_ENABLED 1 +#cmakedefine DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT 1 // NOLINTEND(cppcoreguidelines-macro-to-enum) diff --git a/src/utility/filesystem_extractor.cpp b/src/utility/filesystem_extractor.cpp index 08e8b393..f5317612 100644 --- a/src/utility/filesystem_extractor.cpp +++ b/src/utility/filesystem_extractor.cpp @@ -47,6 +47,7 @@ #include #include +#include #include #include #include @@ -121,8 +122,11 @@ class filesystem_extractor_ final : public filesystem_extractor::impl { } } - void open_archive(std::filesystem::path const& output, - std::string const& format) override { + void open_archive(std::filesystem::path const& output [[maybe_unused]], + std::string const& format [[maybe_unused]]) override { +#ifdef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT + DWARFS_THROW(runtime_error, "open_archive() not supported in this build"); +#else LOG_DEBUG << "opening archive file in " << format << " format"; a_ = ::archive_write_new(); @@ -136,10 +140,15 @@ class filesystem_extractor_ final : public filesystem_extractor::impl { #else check_result(::archive_write_open_filename( a_, output.empty() ? nullptr : output.string().c_str())); +#endif #endif } - void open_stream(std::ostream& os, std::string const& format) override { + void open_stream(std::ostream& os [[maybe_unused]], + std::string const& format [[maybe_unused]]) override { +#ifdef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT + DWARFS_THROW(runtime_error, "open_stream() not supported in this build"); +#else #ifdef _WIN32 if (::_pipe(pipefd_.data(), 8192, _O_BINARY) != 0) { DWARFS_THROW(system_error, "_pipe()"); @@ -160,6 +169,7 @@ class filesystem_extractor_ final : public filesystem_extractor::impl { check_result(::archive_write_set_format_by_name(a_, format.c_str())); check_result(::archive_write_set_bytes_in_last_block(a_, 1)); check_result(::archive_write_open_fd(a_, pipefd_[1])); +#endif } void open_disk(std::filesystem::path const& output) override { diff --git a/test/compat_test.cpp b/test/compat_test.cpp index 5692f82e..e18d422d 100644 --- a/test/compat_test.cpp +++ b/test/compat_test.cpp @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -869,7 +870,7 @@ void walk_tree(reader::filesystem_v2 const& fs, T& cb, } } -void check_compat(logger& lgr, reader::filesystem_v2 const& fs, +void check_compat(logger& lgr [[maybe_unused]], reader::filesystem_v2 const& fs, std::string const& version, bool enable_nlink) { bool const has_devices = not(version == "0.2.0" or version == "0.2.3"); bool const has_ac_time = version == "0.2.0" or version == "0.2.3"; @@ -1079,6 +1080,7 @@ void check_compat(logger& lgr, reader::filesystem_v2 const& fs, } } +#ifndef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT test::os_access_mock os; utility::filesystem_extractor ext(lgr, os); std::ostringstream oss; @@ -1111,6 +1113,7 @@ void check_compat(logger& lgr, reader::filesystem_v2 const& fs, } EXPECT_EQ(ref_entries.size(), mtree.size()); +#endif std::map> testdirs{ {"empty", {"empty/alsoempty"}}, diff --git a/test/manpage_test.cpp b/test/manpage_test.cpp index e9260d5a..562dfc4b 100644 --- a/test/manpage_test.cpp +++ b/test/manpage_test.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -190,6 +191,15 @@ TEST_P(manpage_coverage_test, options) { } } + if (tool_name == "dwarfsextract") { +#ifdef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT + man_opts.erase("format"); +#endif +#ifdef DWARFSEXTRACT_MINIMAL + man_opts.erase("pattern"); +#endif + } + for (auto const& [opt, short_opt] : man_opts) { auto it = help_opts.find(opt); if (it == help_opts.end()) { diff --git a/test/tool_main_test.cpp b/test/tool_main_test.cpp index d6409708..973f1307 100644 --- a/test/tool_main_test.cpp +++ b/test/tool_main_test.cpp @@ -571,7 +571,8 @@ TEST_F(dwarfsextract_main_test, cmdline_help_arg) { EXPECT_THAT(out(), ::testing::HasSubstr("Usage: dwarfsextract")); } -#if DWARFS_PERFMON_ENABLED +#if DWARFS_PERFMON_ENABLED && \ + !defined(DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT) TEST(dwarfsextract_test, perfmon) { auto t = dwarfsextract_tester::create_with_image(); ASSERT_EQ(0, t.run({"-i", "image.dwarfs", "-f", "mtree", "--perfmon", @@ -2148,6 +2149,7 @@ constexpr std::array const progress_modes{ INSTANTIATE_TEST_SUITE_P(dwarfs, mkdwarfs_progress_test, ::testing::ValuesIn(progress_modes)); +#ifndef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT TEST(dwarfsextract_test, mtree) { auto t = dwarfsextract_tester::create_with_image(); ASSERT_EQ(0, t.run({"-i", "image.dwarfs", "-f", "mtree"})) << t.err(); @@ -2157,6 +2159,7 @@ TEST(dwarfsextract_test, mtree) { EXPECT_THAT(out, ::testing::HasSubstr("type=file")); } +#ifndef DWARFSEXTRACT_MINIMAL TEST(dwarfsextract_test, patterns) { auto mkdt = mkdwarfs_tester::create_empty(); mkdt.add_test_file_tree(); @@ -2187,6 +2190,7 @@ TEST(dwarfsextract_test, patterns) { } EXPECT_EQ(expected, actual); } +#endif TEST(dwarfsextract_test, stdout_progress_error) { auto t = dwarfsextract_tester::create_with_image(); @@ -2326,6 +2330,8 @@ TEST_P(dwarfsextract_format_test, basic) { INSTANTIATE_TEST_SUITE_P(dwarfs, dwarfsextract_format_test, ::testing::ValuesIn(libarchive_formats)); +#endif + TEST(dwarfsck_test, check_exclusive) { auto t = dwarfsck_tester::create_with_image(); EXPECT_NE(0, t.run({"image.dwarfs", "--no-check", "--check-integrity"})) diff --git a/test/tools_test.cpp b/test/tools_test.cpp index a8d56577..80bc7805 100644 --- a/test/tools_test.cpp +++ b/test/tools_test.cpp @@ -1813,14 +1813,20 @@ INSTANTIATE_TEST_SUITE_P( TEST(tools_test, dwarfsextract_progress) { dwarfs::temporary_directory tempdir("dwarfs"); auto td = tempdir.path(); +#ifdef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT + auto out = subprocess::check_run(dwarfsextract_bin, "-i", test_catdata_dwarfs, + "-o", td.string(), "--stdout-progress"); + EXPECT_TRUE(fs::exists(td / "pcmaudio" / "test12.aiff")); +#else auto tarfile = td / "output.tar"; auto out = subprocess::check_run(dwarfsextract_bin, "-i", test_catdata_dwarfs, "-o", tarfile, "-f", "gnutar", "--stdout-progress"); - ASSERT_TRUE(out); EXPECT_TRUE(fs::exists(tarfile)); +#endif + ASSERT_TRUE(out); EXPECT_GT(out->size(), 100) << *out; #ifdef _WIN32 EXPECT_THAT(*out, ::testing::EndsWith("100%\r\n")); @@ -1830,6 +1836,7 @@ TEST(tools_test, dwarfsextract_progress) { #endif } +#ifndef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT TEST(tools_test, dwarfsextract_stdout) { dwarfs::temporary_directory tempdir("dwarfs"); auto td = tempdir.path(); @@ -1862,6 +1869,7 @@ TEST(tools_test, dwarfsextract_file_out) { EXPECT_THAT(mtree, ::testing::StartsWith("#mtree\n")); EXPECT_THAT(mtree, ::testing::HasSubstr("type=file")); } +#endif #ifdef _WIN32 TEST(tools_test, mkdwarfs_invalid_utf8_filename) { diff --git a/tools/src/dwarfsextract_main.cpp b/tools/src/dwarfsextract_main.cpp index 3b5708fc..d25c3b90 100644 --- a/tools/src/dwarfsextract_main.cpp +++ b/tools/src/dwarfsextract_main.cpp @@ -57,18 +57,23 @@ namespace dwarfs::tool { namespace { +#ifndef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT #ifdef _WIN32 constexpr std::wstring_view kDash{L"-"}; #else constexpr std::string_view kDash{"-"}; #endif +#endif } // namespace int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) { sys_string fs_image, output, trace_file; - std::string format, cache_size_str, image_offset; + std::string cache_size_str, image_offset; logger_options logopts; +#ifndef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT + std::string format; +#endif #if DWARFS_PERFMON_ENABLED std::string perfmon_str; #endif @@ -85,15 +90,19 @@ int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) { ("output,o", po_sys_value(&output), "output file or directory") +#ifndef DWARFSEXTRACT_MINIMAL ("pattern", po::value>(), "only extract files matching these patterns") +#endif ("image-offset,O", po::value(&image_offset)->default_value("auto"), "filesystem image offset in bytes") +#ifndef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT ("format,f", po::value(&format), "output format") +#endif ("continue-on-error", po::value(&continue_on_error)->zero_tokens(), "continue if errors are encountered") @@ -123,7 +132,9 @@ int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) { tool::add_common_options(opts, logopts); po::positional_options_description pos; +#ifndef DWARFSEXTRACT_MINIMAL pos.add("pattern", -1); +#endif po::variables_map vm; @@ -161,10 +172,12 @@ int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) { std::unique_ptr matcher; +#ifndef DWARFSEXTRACT_MINIMAL if (vm.contains("pattern")) { matcher = std::make_unique( vm["pattern"].as>()); } +#endif int rv = 0; @@ -194,8 +207,11 @@ int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) { reader::filesystem_v2_lite fs(lgr, *iol.os, fs_image, fsopts, perfmon); utility::filesystem_extractor fsx(lgr, *iol.os); +#ifndef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT if (format.empty()) { +#endif fsx.open_disk(iol.os->canonical(output)); +#ifndef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT } else { std::ostream* stream{nullptr}; @@ -218,6 +234,7 @@ int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) { fsx.open_archive(iol.os->canonical(output), format); } } +#endif utility::filesystem_extractor_options fsx_opts;