我遇到过通过
zipnote
重命名zip文件的情况,如下
$ echo -e "@ -\n@=newname.sql" | zipnote -w file.zip
zipnote error: Bad file descriptor
zipnote error: Temporary file failure (zisC9HAb
我注意到,这个错误已在Zip 3.1b beta中修复,补丁集可以在this gist post
中下载所以,我尝试从源代码构建Info-Zip(通过
make -f unix/Makefile generic
),但是它显示错误:error: conflicting types for 'memset'/'memcpy'/'memcmp'
(完整日志)。
这是我的步骤:
# download zip30 source code
$ curl -fsSL ftp://ftp.info-zip.org/pub/infozip/src/zip30.zip | bsdtar xzf - -C /tmp/
# download patchset
$ curl -o /tmp/zipinfo.patch -fsSL https://gist.githubusercontent.com/marslo/70a3f6728633c49bed865da684378b31/raw/cf402112315ededbfb58c0e17629e9a74708e370/zipinfo.patch
# apply patchset
$ cd /tmp/zip30
$ patch -u zipnote.c -i ../zipinfo.patch
$ make -f unix/Makefile generic
...
eval /Applications/Xcode.app/Contents/Developer/usr/bin/make -f unix/Makefile zips `cat flags`
cc -c -I. -DUNIX -O3 -DBZIP2_SUPPORT -DUIDGID_NOT_16BIT -DLARGE_FILE_SUPPORT -DUNICODE_SUPPORT -DNO_RMDIR -DNO_STRCHR -DNO_STRRCHR -DNO_RENAME -DNO_MKTEMP -DNO_MKTIME -DNO_MKSTEMP -DZMEM -DNO_ERRNO -DNO_DIR -DHAVE_DIRENT_H -DHAVE_TERMIOS_H -DNO_VALLOC zip.c
In file included from zip.c:16:
./zip.h:726:10: error: conflicting types for 'memset'
726 | char *memset OF((char *, int, unsigned int));
| ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_string.h:74:7: note: previous declaration is here
74 | void *memset(void *__b, int __c, size_t __len);
| ^
In file included from zip.c:16:
./zip.h:727:10: error: conflicting types for 'memcpy'
727 | char *memcpy OF((char *, char *, unsigned int));
| ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_string.h:72:7: note: previous declaration is here
72 | void *memcpy(void *__dst, const void *__src, size_t __n);
| ^
In file included from zip.c:16:
./zip.h:728:8: error: conflicting types for 'memcmp'
728 | int memcmp OF((char *, char *, unsigned int));
| ^
...
$ sw_vers
ProductName: macOS
ProductVersion: 14.7.2
BuildVersion: 23H311
$ uname -a
Darwin iMarslo 23.6.0 Darwin Kernel Version 23.6.0: Fri Nov 15 15:12:37 PST 2024; root:xnu-10063.141.1.702.7~1/RELEASE_ARM64_T6030 arm64 arm Darwin
$ xcodebuild -version
Xcode 16.1
Build version 16B40
$ llvm-config --version
19.1.5
顺便说一下,我已经看到默认的 zip 是通过 LLVM 构建的,我怎样才能使用相同的编译器?
$ which -a zip
/usr/bin/zip
$ /usr/bin/zip --version
...
Compiled with gcc Apple LLVM 15.0.0 (clang-1500.3.9.1) [+internal-os] for Unix (Mac OS X) on Jul 19 2024.
ruby.rb
:
# Fix compile with newer Clang
# Otherwise configure thinks memset() and others are missing
patch do
url "https://raw.githubusercontent.com/Homebrew/formula-patches/d2b59930/zip/xcode15.diff"
sha256 "99cb7eeeb6fdb8df700f40bfffbc30516c94774cbf585f725d81c3224a2c530c"
end
def install
system "make", "-f", "unix/Makefile", "CC=#{ENV.cc}", "generic"
system "make", "-f", "unix/Makefile", "BINDIR=#{bin}", "MANDIR=#{man1}", "install"
end
所以,完整的步骤应该是:
# -- download zip30 source code --
$ curl -fsSL ftp://ftp.info-zip.org/pub/infozip/src/zip30.zip | bsdtar xzf - -C /tmp/
# -- download patchset --
$ curl -o /tmp/zipinfo.patch -fsSL https://gist.githubusercontent.com/marslo/70a3f6728633c49bed865da684378b31/raw/cf402112315ededbfb58c0e17629e9a74708e370/zipinfo.patch
$ curl -o /tmp/xcode15.patch -fsSL https://raw.githubusercontent.com/Homebrew/formula-patches/d2b59930/zip/xcode15.diff
$ cd /tmp/zip30
# -- apply patchset --
# apply patchset to resolve zipnote issue
$ patch -u zipnote.c -i ../zipinfo.patch
# apply patchset to avoid memset in macos
$ patch -u unix/configure -i ../xcode15.patch
# -- build zip --
# with LLVM Clang
$ make -f unix/Makefile generic
# with gcc
$ make -f unix/Makefile CC=clang generic
# -- install --
# i.e.:
# - bin: /tmp/bin
# - man: /tmp/man
$ make -f unix/Makefile BINDIR=/tmp/bin MANDIR=/tmp/man install
$ make -f unix/Makefile BINDIR=/tmp/bin MANDIR=/tmp/man install
mkdir -p /tmp/bin
cp zip zipcloak zipnote zipsplit /tmp/bin
cd /tmp/bin; chmod 755 zip zipcloak zipnote zipsplit
mkdir -p /tmp/man
cp man/zip.1 /tmp/man/zip.1
chmod 644 /tmp/man/zip.1
cp man/zipcloak.1 /tmp/man/zipcloak.1
chmod 644 /tmp/man/zipcloak.1
cp man/zipnote.1 /tmp/man/zipnote.1
chmod 644 /tmp/man/zipnote.1
cp man/zipsplit.1 /tmp/man/zipsplit.1
chmod 644 /tmp/man/zipsplit.1
# check version
$ /tmp/bin/zip --version
...
Compiled with gcc Apple LLVM 16.0.0 (clang-1600.0.26.4) for Unix (Mac OS X) on Dec 12 2024.
...
# rename files inside zip
$ echo 'foo bar' | zip > file.zip
adding: - (stored 0%)
$ unzip -l file.zip
Archive: file.zip
Length Date Time Name
--------- ---------- ----- ----
8 12-12-2024 02:01 - # file named `-`
--------- -------
8 1 file
# rename `-` to `filename.txt`
$ printf "@ -\n@=filename.txt\n" | /tmp/bin/zipnote -w file.zip
$ unzip -l file.zip
Archive: file.zip
Length Date Time Name
--------- ---------- ----- ----
8 12-12-2024 02:01 filename.txt # renamed to `filename.txt`
--------- -------
8 1 file