macoszip

how to build Info-Zip for macos


I've encountered the zip file renaming via zipnote as below

$ echo -e "@ -\n@=newname.sql" | zipnote -w file.zip 
zipnote error: Bad file descriptor
zipnote error: Temporary file failure (zisC9HAb

And I noticed that, this error has been fixed in Zip 3.1b beta, and the patchset can be downloaded in this gist post

So, I've tried to build the Info-Zip from source ( via make -f unix/Makefile generic ), however it shows error: error: conflicting types for 'memset'/'memcpy'/'memcmp' ( full log ).


Here are my steps:

setup code folder

# 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

build from source

$ 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));
      |        ^
...

macos info

$ 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

By the way, I've seen the default zip was built via LLVM, how can I use the same compiler as well ?

$ 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.

Solution

  • okay, I got the clue from zip brew formula ruby script zip.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
    

    so, the full step should be :

    prepare

    # -- 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 and install

    # -- 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
    

    verify

    # 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
    

    BTW, I've created the unix/configure patch file for Zip 3.1d-BETA ( zip31d.zip ) for macOS base on patch for zip30, here are results:

    $ ./zip --version
    Copyright (c) 1990-2015 Info-ZIP - Type 'zip -L' for software license.
    This is Zip 3.1d-BETA (November 15th 2015), by Info-ZIP.
    Currently maintained by E. Gordon.  Please send bug reports to
    the authors using the web page at www.info-zip.org; see README for details.
    
    Latest sources and executables are at ftp://ftp.info-zip.org/pub/infozip,
    as of above date; see http://www.info-zip.org/ for other sites.
    
    Compiled with LLVM Clang 16.0.0 (GCC 4.2.1) for Unix (Darwin 23.6.0 arm) on Dec 12 2024.