Subject: Re: bug#53534: 28.0.91; on netbsd 'gmake install' outputs 'find: chown: No such file or directory'

From: Glenn Morris <[email-masked]>
Date: Wed, 26 Jan 2022 21:22:54 -0500

Here's a patch to use cp -R in preference to tar+chown+chmod.

--- i/Makefile.in
+++ w/Makefile.in
@@ -576,6 +576,12 @@ INSTALL_ARCH_INDEP_EXTRA = @INSTALL_ARCH_INDEP_EXTRA@
 
 ## https://lists.gnu.org/r/emacs-devel/2007-10/msg01672.html
 ## Needs to be the user running install, so configure can't set it.
+## This is only used if we use tar to copy rather than cp -R.
+## I think it is buggy, eg if you 'su' to root LOGNAME etc do not change,
+## whereas if you 'su -' they do.  Since the need to run chown only
+## occurs for root, it would probably be better to only chown if UID
+## is 0, and just chown to root.  But the entire tar branch is
+## obsolete and unlikely to be used in practice.
 set_installuser=for installuser in $${LOGNAME} $${USERNAME} $${USER} \
 	  `(id -u) 2> /dev/null`; do \
 	  [ -n "$${installuser}" ] && break ; \
@@ -613,12 +619,15 @@ set_installuser=for installuser in $${LOGNAME} $${USERNAME} $${USER} \
 ## but not add subdirs.el to them.  This was a strange halfway house.
 ## Nowadays we do not create non-default directories.
 
-## Note that we use tar instead of plain old cp -R/-r because the latter
-## is apparently not portable (even in 2012!).
+## Historically this used tar, possibly due to portability concerns with cp -R.
+## Using tar introduces issues with ownership and permission when run as root.
+## Hence the chowns and chmods, the latter because "umask 022; tar
+## ..." is not guaranteed to do the right thing if we are root and tar
+## is preserving source permissions.
+##
+## It seems highly likely that cp -R works on all relevant platforms,
+## so in 2022 the tar fallback is probably unnecessary.  Refs:
 ## https://lists.gnu.org/r/emacs-devel/2012-05/msg00278.html
-## I have no idea which platforms Emacs supports where cp -R does not
-## work correctly, and therefore no idea when tar can be replaced.
-## See also these comments from 2004 about cp -r working fine:
 ## https://lists.gnu.org/r/autoconf-patches/2004-11/msg00005.html
 install-arch-indep: lisp install-info install-man ${INSTALL_ARCH_INDEP_EXTRA}
 	umask 022 && $(MKDIR_P) "$(DESTDIR)$(includedir)"
@@ -637,9 +646,14 @@ install-arch-indep: lisp install-info install-man ${INSTALL_ARCH_INDEP_EXTRA}
 	  rm -rf "$${dest}" ; \
 	  umask 022; ${MKDIR_P} "$${dest}" ; \
 	  printf 'Copying %s to %s...\n' "$$dir" "$$dest" ; \
-	  (cd $${dir}; tar -chf - . ) \
-	    | (cd "$${dest}"; umask 022; \
-	       tar -xvf - && cat > /dev/null) || exit 1; \
+	  dotar= ; \
+	  destbase=`echo "$${dest}" | sed 's,/[^/]*$$,,'`; \
+	  if ! cp -R "$$dir" "$$destbase"; then \
+	    dotar=t; \
+	    (cd $${dir}; tar -chf - . ) \
+	      | (cd "$${dest}"; umask 022; \
+	         tar -xvf - && cat > /dev/null) || exit 1; \
+	  fi; \
 	  if [ "$${dir}" = "${srcdir}/etc" ]; then \
 	      rm -f "$${dest}/DOC"* ; \
 	      rm -f "$${dest}/refcards"/*.aux "$${dest}/refcards"/*.dvi; \
@@ -648,7 +662,7 @@ install-arch-indep: lisp install-info install-man ${INSTALL_ARCH_INDEP_EXTRA}
 	  fi; \
 	  (cd "$${dest}" || exit 1; \
 	    for subdir in `find . -type d -print` ; do \
-	      chmod a+rx $${subdir} ; \
+	      [ -z "$$dotar" ] || chmod a+rx $${subdir} ; \
 	      rm -f $${subdir}/.gitignore ; \
 	      rm -f $${subdir}/.arch-inventory ; \
 	      rm -f $${subdir}/.DS_Store ; \
@@ -660,7 +674,8 @@ install-arch-indep: lisp install-info install-man ${INSTALL_ARCH_INDEP_EXTRA}
 	      [ "$${dir}" != "${srcdir}/etc" ] && \
 	        rm -f $${subdir}/[mM]akefile*[.-]in $${subdir}/[mM]akefile ; \
 	    done ); \
-	  find "$${dest}" -exec chown $${installuser} {} ';' ;\
+	  [ -z "$$dotar" ] || \
+	    find "$${dest}" -exec chown $${installuser} {} ';' ;\
 	done
 	-rm -f "$(DESTDIR)${lispdir}/subdirs.el"
 	umask 022; $(srcdir)/build-aux/update-subdirs "$(DESTDIR)${lispdir}"
@@ -678,9 +693,7 @@ install-arch-indep: lisp install-info install-man ${INSTALL_ARCH_INDEP_EXTRA}
 	}
 	-chmod -R a+r "$(DESTDIR)${datadir}/emacs/${version}" ${COPYDESTS}
 
-## The above chmods are needed because "umask 022; tar ..." is not
-## guaranteed to do the right thing; eg if we are root and tar is
-## preserving source permissions.
+## Final chmod above is not needed if we did not use tar.
 
 ## Note that install-arch-indep deletes and recreates the entire
 ## installed etc/ directory, so we need it to run before this does.