Building debian package fails when destination is /usr/local/bin

Eri*_*rik 5 packaging debian

I created a very simple C project and want to build a debian package from it.\nManually building the C project via the Makefile works as expected, it build the binary and can be installed in /usr/local/bin. When trying to build a debian packages however it fails with\ndh_usrlocal: error: debian/myhelloworld/usr/local/bin/myhelloworld is not a directory

\n

The Makefile looks like this:

\n
prefix = /usr/local/bin\n\nall: src/myhelloworld\n\nsrc/hello: src/myhelloworld.c\n    @echo "CFLAGS=$(CFLAGS)" | \\\n        fold -s -w 70 | \\\n        sed -e 's/^/# /'\n    $(CC) $(CPPFLAGS) $(CFLAGS) $(LDCFLAGS) -o $@ $^\n\ninstall: src/myhelloworld\n    install -D src/myhelloworld \\\n        $(DESTDIR)$(prefix)/myhelloworld\n\nclean:\n    -rm -f src/myhelloworld\n\ndistclean: clean\n\nuninstall:\n    -rm -f $(DESTDIR)$(prefix)/myhelloworld\n\n.PHONY: all install clean distclean uninstall\n\n
Run Code Online (Sandbox Code Playgroud)\n

The debian directory is created with debmake and i use debuild for building.

\n

The project structure looks like:

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 debian\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 changelog\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 control\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 copyright\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 debhelper-build-stamp\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 files\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 myhelloworld\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 DEBIAN\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 control\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 md5sums\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 usr\n\xe2\x94\x82   \xe2\x94\x82       \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 myhelloworld\n\xe2\x94\x82   \xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 share\n\xe2\x94\x82   \xe2\x94\x82           \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 doc\n\xe2\x94\x82   \xe2\x94\x82               \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 myhelloworld\n\xe2\x94\x82   \xe2\x94\x82                   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 changelog.Debian.gz\n\xe2\x94\x82   \xe2\x94\x82                   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 copyright\n\xe2\x94\x82   \xe2\x94\x82                   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 README.Debian\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 myhelloworld.debhelper.log\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 myhelloworld.substvars\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 patches\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 series\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 README.Debian\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 rules\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 source\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 format\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 local-options\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 watch\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 LICENSE\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Makefile\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 src\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 myhelloworld\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 myhelloworld.c\n
Run Code Online (Sandbox Code Playgroud)\n

I have tried to change the default debian/rules file to override the dh_auto_install so it looks like:

\n
%:\n    dh $@  \n\noverride_dh_auto_install:\n    dh_auto_install -- prefix=/usr/local/bin\n
Run Code Online (Sandbox Code Playgroud)\n

This fails too.\nI did check that the binary does exist in debian/myhelloworld/usr/local/bin.

\n

I tried to change the prefix to just /usr/bin. This makes it possible to successfully build the package, but the containing binary is now installed in /usr/bin.

\n

从错误消息来看,debuild 似乎期望是myhelloworld一个目录,但这是二进制文件。\n那么为什么 debuild 在我的/usr/local/bin目标上失败。

\n

构建日志:

\n
ep@ep-xps:~/sandbox/myhelloworld-1.0$ debuild \n dpkg-buildpackage -us -uc -ui\ndpkg-buildpackage: info: source package myhelloworld\ndpkg-buildpackage: info: source version 1.0-1\ndpkg-buildpackage: info: source distribution UNRELEASED\ndpkg-buildpackage: info: source changed by Erik <>\n dpkg-source --before-build .\ndpkg-buildpackage: info: host architecture amd64\n fakeroot debian/rules clean\ndh clean  \n   dh_auto_clean\n        make -j12 distclean\nmake[1]: Entering directory '/home/ep/sandbox/myhelloworld-1.0'\nrm -f src/myhelloworld\nmake[1]: Leaving directory '/home/ep/sandbox/myhelloworld-1.0'\n   dh_clean\n dpkg-source -b .\ndpkg-source: warning: no source format specified in debian/source/format, see dpkg-source(1)\ndpkg-source: info: using source format '1.0'\ndpkg-source: info: building myhelloworld using existing myhelloworld_1.0.orig.tar.gz\ndpkg-source: info: building myhelloworld in myhelloworld_1.0-1.diff.gz\ndpkg-source: warning: newly created empty file 'LICENSE' will not be represented in diff\ndpkg-source: warning: the diff modifies the following upstream files: \n Makefile\n src/myhelloworld.c\ndpkg-source: info: use the '3.0 (quilt)' format to have separate and documented changes to upstream files, see dpkg-source(1)\ndpkg-source: info: building myhelloworld in myhelloworld_1.0-1.dsc\n debian/rules build\ndh build  \n   dh_update_autotools_config\n   dh_autoreconf\n   dh_auto_configure\n   dh_auto_build\n        make -j12 "INSTALL=install --strip-program=true"\nmake[1]: Entering directory '/home/ep/sandbox/myhelloworld-1.0'\ncc -g -O2 -ffile-prefix-map=/home/ep/sandbox/myhelloworld-1.0=. -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -flto=auto -ffat-lto-objects -flto=auto -Wl,-z,relro  src/myhelloworld.c   -o src/myhelloworld\nmake[1]: Leaving directory '/home/ep/sandbox/myhelloworld-1.0'\n   dh_auto_test\n   create-stamp debian/debhelper-build-stamp\n fakeroot debian/rules binary\ndh binary  \n   dh_testroot\n   dh_prep\n   debian/rules override_dh_auto_install\nmake[1]: Entering directory '/home/ep/sandbox/myhelloworld-1.0'\ndh_auto_install -- prefix=/usr/local/bin\n        make -j12 install DESTDIR=/home/ep/sandbox/myhelloworld-1.0/debian/myhelloworld AM_UPDATE_INFO_DIR=no "INSTALL=install --strip-program=true" prefix=/usr/local/bin\nmake[2]: Entering directory '/home/ep/sandbox/myhelloworld-1.0'\ninstall -D src/myhelloworld \\\n        /home/ep/sandbox/myhelloworld-1.0/debian/myhelloworld/usr/local/bin/myhelloworld\nmake[2]: Leaving directory '/home/ep/sandbox/myhelloworld-1.0'\nmake[1]: Leaving directory '/home/ep/sandbox/myhelloworld-1.0'\n   dh_installdocs\n   dh_installchangelogs\n   dh_perl\n   dh_usrlocal\ndh_usrlocal: error: debian/myhelloworld/usr/local/bin/myhelloworld is not a directory\nmake: *** [debian/rules:9: binary] Error 25\ndpkg-buildpackage: error: fakeroot debian/rules binary subprocess returned exit status 2\ndebuild: fatal error at line 1182:\ndpkg-buildpackage -us -uc -ui failed\n\n\n
Run Code Online (Sandbox Code Playgroud)\n

Ste*_*itt 8

软件包\xe2\x80\x99t 不允许在目录中传送文件/usr/local,这是由dh_usrlocal.

\n

最好的解决办法是遵循 Debian 约定并安装在/usr:

\n
override_dh_auto_install:\n        dh_auto_install -- prefix=/usr/bin\n
Run Code Online (Sandbox Code Playgroud)\n

如果您确实想安装到/usr/local/bin,请覆盖dh_usrlocal instead:

\n
override_dh_usrlocal:\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,前缀通常被理解为 \xe2\x80\x9croot\xe2\x80\x9d,其下放置各种目录,因此你\xe2\x80\x99d 有

\n
prefix = /usr/local\n\n\xe2\x80\xa6\n\ninstall: src/myhelloworld\n        install -D src/myhelloworld \\\n            $(DESTDIR)$(prefix)/bin/myhelloworld\n
Run Code Online (Sandbox Code Playgroud)\n

这就是为什么您最初尝试安装myhelloworld/usr:dh_auto_install设置prefix/usr. 如果您将其更改Makefile为上述内容,则可以dh_auto_install完全放弃覆盖。

\n

(你的\xe2\x80\x99s中有一个轻微的拼写错误Makefile,应该是 $(LDFLAGS),而不是$(LDCFLAGS)。)

\n

您可能会发现Debian 上游指南很有用。

\n

  • 不太确定为什么我想要 /usr/local/bin,但是 `override_dh_usrlocal:` 在这种情况下可以解决问题。毕竟,坚持使用“/usr/bin”的指导方针似乎是最好的方法。非常感谢您的解释。 (2认同)