From 89571de0f3a23a9ada08ed4cc2b0d2c5683f23e9 Mon Sep 17 00:00:00 2001 From: Marcus Holland-Moritz Date: Mon, 10 Jul 2023 18:41:39 +0200 Subject: [PATCH] Symbolic links for the universal binary also work on Windows --- README.md | 23 ++++++++++++++++------- src/universal.cpp | 15 ++++++++++----- test/dwarfs_tools.cpp | 12 +++++------- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index b377cdea..ccabb3ab 100644 --- a/README.md +++ b/README.md @@ -128,24 +128,33 @@ FUSE driver) in a single executable. These executables are compressed using [upx](https://github.com/upx/upx), so they are much smaller than the individual tools combined. -The universal binaries can be run either through symbolic links named -after the proper tool. e.g.: +The universal binaries can be run through symbolic links named after +the proper tool. e.g.: ``` -$ ln -s dwarfs-universal-0.7.0-RC5-Linux-aarch64 mkdwarfs +$ ln -s dwarfs-universal-0.7.0-Linux-aarch64 mkdwarfs $ ./mkdwarfs --help ``` -Or you can select the tool by passing `--tool=` as the first -argument on the command line: +This also works on Windows ift the file system supports symbolic links: ``` -$ .\dwarfs-universal-0.7.0-RC5-Windows-AMD64.exe --tool=mkdwarfs --help +> mklink mkdwarfs.exe dwarfs-universal-0.7.0-Windows-AMD64.exe +> .\mkdwarfs.exe --help +``` + +Alternatively, you can select the tool by passing `--tool=` as +the first argument on the command line: + +``` +> .\dwarfs-universal-0.7.0-Windows-AMD64.exe --tool=mkdwarfs --help ``` Note that just like the `dwarfs.exe` Windows binary, the universal Windows binary depends on the `winfsp-x64.dll` from the -[WinFsp](https://github.com/winfsp/winfsp) project. +[WinFsp](https://github.com/winfsp/winfsp) project. However, for the +universal binary, the DLL is loaded lazily, so you can still use all +other tools without the DLL. See the [Windows Support](#windows-support) section for more details. ### Dependencies diff --git a/src/universal.cpp b/src/universal.cpp index 9e4586f5..a937b3e5 100644 --- a/src/universal.cpp +++ b/src/universal.cpp @@ -87,6 +87,12 @@ int dwarfs_main_helper(int argc, sys_char** argv) { } #endif +#ifdef _WIN32 +#define EXE_EXT ".exe" +#else +#define EXE_EXT "" +#endif + std::map const functions{ #ifdef _WIN32 {"dwarfs", &dwarfs_main_helper}, @@ -120,14 +126,13 @@ int SYS_MAIN(int argc, sys_char** argv) { } } -#ifndef _WIN32 auto path = std::filesystem::path(argv[0]); - if (auto it = functions.find(path.filename().string()); - it != functions.end()) { - return safe_main([&] { return it->second(argc, argv); }); + if (path.extension().string() == EXE_EXT) { + if (auto it = functions.find(path.stem().string()); it != functions.end()) { + return safe_main([&] { return it->second(argc, argv); }); + } } -#endif using namespace folly::gen; diff --git a/test/dwarfs_tools.cpp b/test/dwarfs_tools.cpp index e87f19bf..d1487771 100644 --- a/test/dwarfs_tools.cpp +++ b/test/dwarfs_tools.cpp @@ -589,9 +589,7 @@ enum class binary_mode { std::vector tools_test_modes{ binary_mode::standalone, binary_mode::universal_tool, -#ifndef _WIN32 binary_mode::universal_symlink, -#endif }; class tools_test : public ::testing::TestWithParam {}; @@ -608,10 +606,10 @@ TEST_P(tools_test, end_to_end) { auto image_hdr = td / "test_hdr.dwarfs"; auto fsdata_dir = td / "fsdata"; auto header_data = fsdata_dir / "format.sh"; - auto universal_symlink_dwarfs_bin = td / "dwarfs"; - auto universal_symlink_mkdwarfs_bin = td / "mkdwarfs"; - auto universal_symlink_dwarfsck_bin = td / "dwarfsck"; - auto universal_symlink_dwarfsextract_bin = td / "dwarfsextract"; + auto universal_symlink_dwarfs_bin = td / "dwarfs" EXE_EXT; + auto universal_symlink_mkdwarfs_bin = td / "mkdwarfs" EXE_EXT; + auto universal_symlink_dwarfsck_bin = td / "dwarfsck" EXE_EXT; + auto universal_symlink_dwarfsextract_bin = td / "dwarfsextract" EXE_EXT; std::vector mkdwarfs_tool_arg; std::vector dwarfsck_tool_arg; std::vector dwarfsextract_tool_arg; @@ -897,7 +895,7 @@ TEST_P(tools_test, mutating_ops) { auto non_empty_dir = mountpoint / "foo"; auto name_inside_fs = mountpoint / "some_random_name"; auto name_outside_fs = td / "some_random_name"; - auto universal_symlink_dwarfs_bin = td / "dwarfs"; + auto universal_symlink_dwarfs_bin = td / "dwarfs" EXE_EXT; if (mode == binary_mode::universal_symlink) { fs::create_symlink(universal_bin, universal_symlink_dwarfs_bin);