openwrt / packages

Community maintained packages for OpenWrt. Documentation for submitting pull requests is in CONTRIBUTING.md
GNU General Public License v2.0
3.93k stars 3.44k forks source link

git: Installed Size Twice Needed; ~2.4 MB Savings #5751

Closed jeffsf closed 6 years ago

jeffsf commented 6 years ago

Maintainer: @tripolar Environment: Archer C7

Description: At least three large binaries are replicated -- ~2.4 MB savings appear possible

On installing git_2.16.1-2_mips_24kc.ipk it appears that at least

are replicated in /usr/bin and /usr/lib/git-core They appear to be identical binaries, yet distinct files in the two locations.

Replacement of the "duplicate" with a link for these would save roughly 2.4 MB, very significant on 16 MB systems.

root@OpenWrt:/tmp# files='git git-shell git-upload-pack'
root@OpenWrt:/tmp# for f in $files ; do ls -l /usr/bin/$f ; done
-rwxr-xr-x    1 root     root       1229669 Mar 11 07:58 /usr/bin/git
-rwxr-xr-x    1 root     root        627669 Mar 11 07:58 /usr/bin/git-shell
-rwxr-xr-x    1 root     root        677045 Mar 11 07:58 /usr/bin/git-upload-pack
root@OpenWrt:/tmp# for f in $files ; do ls -l /usr/lib/git-core/$f ; done
-rwxr-xr-x    1 root     root       1229669 Mar 11 07:58 /usr/lib/git-core/git
-rwxr-xr-x    1 root     root        627669 Mar 11 07:58 /usr/lib/git-core/git-shell
-rwxr-xr-x    1 root     root        677045 Mar 11 07:58 /usr/lib/git-core/git-upload-pack
root@OpenWrt:/tmp# for f in $files ; do sha256sum /usr/bin/$f ; done
ae077534b815042c121733d849044b71469b44b7e02c3f746183ebb4cd70df57  /usr/bin/git
466d84028559fb1002f6a455fb645645601bb6e96d811c8b7e59696c1f531eea  /usr/bin/git-shell
23dc61e4e062c0a35a4944ce7cb10cc606e71e5c26573ee0dceef9bf15e943b6  /usr/bin/git-upload-pack
root@OpenWrt:/tmp# for f in $files ; do sha256sum /usr/lib/git-core/$f ; done
ae077534b815042c121733d849044b71469b44b7e02c3f746183ebb4cd70df57  /usr/lib/git-core/git
466d84028559fb1002f6a455fb645645601bb6e96d811c8b7e59696c1f531eea  /usr/lib/git-core/git-shell
23dc61e4e062c0a35a4944ce7cb10cc606e71e5c26573ee0dceef9bf15e943b6  /usr/lib/git-core/git-upload-pack

root@OpenWrt:/tmp# for f in $files ; do stat /usr/bin/$f ; done
  File: ‘/usr/bin/git’
  Size: 1229669     Blocks: 2402       IO Block: 1024   regular file
Device: 1f02h/7938d Inode: 546         Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-03-11 07:58:53.000000000 +0000
Modify: 2018-03-11 07:58:53.000000000 +0000
Change: 2018-03-11 07:58:53.000000000 +0000
 Birth: -
  File: ‘/usr/bin/git-shell’
  Size: 627669      Blocks: 1226       IO Block: 1024   regular file
Device: 1f02h/7938d Inode: 514         Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-03-11 07:58:53.000000000 +0000
Modify: 2018-03-11 07:58:53.000000000 +0000
Change: 2018-03-11 07:58:53.000000000 +0000
 Birth: -
  File: ‘/usr/bin/git-upload-pack’
  Size: 677045      Blocks: 1323       IO Block: 1024   regular file
Device: 1f02h/7938d Inode: 542         Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-03-11 07:58:53.000000000 +0000
Modify: 2018-03-11 07:58:53.000000000 +0000
Change: 2018-03-11 07:58:53.000000000 +0000
 Birth: -

root@OpenWrt:/tmp# for f in $files ; do stat /usr/lib/git-core/$f ; done
  File: ‘/usr/lib/git-core/git’
  Size: 1229669     Blocks: 2402       IO Block: 1024   regular file
Device: 1f02h/7938d Inode: 1350        Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-03-11 07:58:53.000000000 +0000
Modify: 2018-03-11 07:58:53.000000000 +0000
Change: 2018-03-11 07:58:53.000000000 +0000
 Birth: -
  File: ‘/usr/lib/git-core/git-shell’
  Size: 627669      Blocks: 1226       IO Block: 1024   regular file
Device: 1f02h/7938d Inode: 1284        Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-03-11 07:58:53.000000000 +0000
Modify: 2018-03-11 07:58:53.000000000 +0000
Change: 2018-03-11 07:58:53.000000000 +0000
 Birth: -
  File: ‘/usr/lib/git-core/git-upload-pack’
  Size: 677045      Blocks: 1323       IO Block: 1024   regular file
Device: 1f02h/7938d Inode: 1345        Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-03-11 07:58:53.000000000 +0000
Modify: 2018-03-11 07:58:53.000000000 +0000
Change: 2018-03-11 07:58:53.000000000 +0000
 Birth: -
``
jeffsf commented 6 years ago

Similar replication appears under Ubuntu

jeffsf commented 6 years ago

In thinking about this, given the authors and the scrutiny of git, there has to be a reason why these are duplicated. The only thing I can think of so far is preventing cross-device links. With most systems running git a couple of MB isn't anything significant, so it is "safer" to just have two copies.

You can't capture if there would be a cross-device link at build time. It would have to be an install-time determination. While busybox is generally configured in OpenWRT to supply at least rudimentary diff and checksum functionality, stat isn't typically supplied. I've been thinking through a post-install script that checks its available options to determine if the pairs of files are "the same" (someone might decide to remove diff or md5sum from their build), and then somehow to determine if there would be a cross-device link (who knows how people configure non-flash storage). Maybe a tiny C helper that calls the system stat(), don't know yet. The "weakest" option would be to write to stderr that script had created a symlink, and that if this bothered you, to fix it (with the appropriate commands shown).

jeffsf commented 6 years ago

It does appear that the Makefile in define Package/git/install tries to symlink git, but there are two copies of git in lede_source/build_dir/target-mips_24kc_musl/git-2.16.1/ipkg-mips_24kc/git

jeffsf commented 6 years ago

Quick hack of the Makefile

diff --git a/net/git/Makefile b/net/git/Makefile
index 1879c49..4806e75 100644
--- a/net/git/Makefile
+++ b/net/git/Makefile
@@ -110,7 +110,10 @@ define Package/git/install
        $(RM) $(PKG_INSTALL_DIR)/usr/bin/git-cvsserver
        $(CP) $(PKG_INSTALL_DIR)/usr/bin/git-* $(1)/usr/bin
        $(INSTALL_DIR) $(1)/usr/lib/git-core
-       $(LN) /usr/bin/git $(1)/usr/lib/git-core/git
+       (cd $(PKG_INSTALL_DIR)/usr/bin                                    ; \
+               $(LN) -sf ../lib/git-core/git             git             ; \
+               $(LN) -sf ../lib/git-core/git-shell       git-shell       ; \
+               $(LN) -sf ../lib/git-core/git-upload-pack git-upload-pack)
        $(INSTALL_DIR) $(1)/usr/share/git-core/templates
        ( cd $(PKG_INSTALL_DIR); $(TAR) \
                --exclude=usr/lib/git-core/git-http-backend \

shows the install size in control dropping from 5,840,761 to 4,312,712. Not sure why it's not a 2,534,383 byte difference, less 75 or so bytes for the symlinks themselves.

lede_source/build_dir/target-mips_24kc_musl/git-2.16.1/ipkg-mips_24kc/git$ ls -l usr/bin/
total 2484
-rwxr-xr-x 1 jeff jeff 1229669 Mar 12 15:46 git
lrwxrwxrwx 1 jeff jeff       3 Mar 12 15:46 git-receive-pack -> git
-rwxr-xr-x 1 jeff jeff  627669 Mar 12 15:46 git-shell
lrwxrwxrwx 1 jeff jeff       3 Mar 12 15:46 git-upload-archive -> git
-rwxr-xr-x 1 jeff jeff  677045 Mar 12 15:46 git-upload-pack
lede_source/build_dir/target-mips_24kc_musl/git-2.16.1/ipkg-mips_24kc/git$ ls -l usr/bin/
total 0
lrwxrwxrwx 1 jeff jeff 19 Mar 12 15:54 git -> ../lib/git-core/git
lrwxrwxrwx 1 jeff jeff  3 Mar 12 15:54 git-receive-pack -> git
lrwxrwxrwx 1 jeff jeff 25 Mar 12 15:54 git-shell -> ../lib/git-core/git-shell
lrwxrwxrwx 1 jeff jeff  3 Mar 12 15:54 git-upload-archive -> git
lrwxrwxrwx 1 jeff jeff 31 Mar 12 15:54 git-upload-pack -> ../lib/git-core/git-upload-pack
tripolar commented 6 years ago

fixed with hardlinks in this commit https://github.com/openwrt/packages/commit/c57adab9f1609dbd09911bc79b967276aeaa8168