当目标为 /usr/local/bin 时构建 debian 软件包失败

当目标为 /usr/local/bin 时构建 debian 软件包失败

我创建了一个非常简单的 C 项目,并想从中构建一个 debian 包。通过 Makefile 手动构建 C 项目可以按预期工作,它构建二进制文件并可以安装在 /usr/local/bin 中。然而,当尝试构建 debian 软件包时,它失败了 dh_usrlocal: error: debian/myhelloworld/usr/local/bin/myhelloworld is not a directory

Makefile 看起来像这样:

prefix = /usr/local/bin

all: src/myhelloworld

src/hello: src/myhelloworld.c
    @echo "CFLAGS=$(CFLAGS)" | \
        fold -s -w 70 | \
        sed -e 's/^/# /'
    $(CC) $(CPPFLAGS) $(CFLAGS) $(LDCFLAGS) -o $@ $^

install: src/myhelloworld
    install -D src/myhelloworld \
        $(DESTDIR)$(prefix)/myhelloworld

clean:
    -rm -f src/myhelloworld

distclean: clean

uninstall:
    -rm -f $(DESTDIR)$(prefix)/myhelloworld

.PHONY: all install clean distclean uninstall

debian 目录是用它创建的debmake,我用debuild它来构建。

项目结构如下:

.
├── debian
│   ├── changelog
│   ├── control
│   ├── copyright
│   ├── debhelper-build-stamp
│   ├── files
│   ├── myhelloworld
│   │   ├── DEBIAN
│   │   │   ├── control
│   │   │   └── md5sums
│   │   └── usr
│   │       ├── myhelloworld
│   │       └── share
│   │           └── doc
│   │               └── myhelloworld
│   │                   ├── changelog.Debian.gz
│   │                   ├── copyright
│   │                   └── README.Debian
│   ├── myhelloworld.debhelper.log
│   ├── myhelloworld.substvars
│   ├── patches
│   │   └── series
│   ├── README.Debian
│   ├── rules
│   ├── source
│   │   ├── format
│   │   └── local-options
│   └── watch
├── LICENSE
├── Makefile
└── src
    ├── myhelloworld
    └── myhelloworld.c

我尝试更改默认debian/rules文件以覆盖 dh_auto_install ,因此它看起来像:

%:
    dh $@  

override_dh_auto_install:
    dh_auto_install -- prefix=/usr/local/bin

这也失败了。我确实检查了二进制文件确实存在于debian/myhelloworld/usr/local/bin.

我尝试将前缀更改为/usr/bin.这使得成功构建包成为可能,但包含的二进制文件现在安装在/usr/bin.

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

构建日志:

ep@ep-xps:~/sandbox/myhelloworld-1.0$ debuild 
 dpkg-buildpackage -us -uc -ui
dpkg-buildpackage: info: source package myhelloworld
dpkg-buildpackage: info: source version 1.0-1
dpkg-buildpackage: info: source distribution UNRELEASED
dpkg-buildpackage: info: source changed by Erik <>
 dpkg-source --before-build .
dpkg-buildpackage: info: host architecture amd64
 fakeroot debian/rules clean
dh clean  
   dh_auto_clean
        make -j12 distclean
make[1]: Entering directory '/home/ep/sandbox/myhelloworld-1.0'
rm -f src/myhelloworld
make[1]: Leaving directory '/home/ep/sandbox/myhelloworld-1.0'
   dh_clean
 dpkg-source -b .
dpkg-source: warning: no source format specified in debian/source/format, see dpkg-source(1)
dpkg-source: info: using source format '1.0'
dpkg-source: info: building myhelloworld using existing myhelloworld_1.0.orig.tar.gz
dpkg-source: info: building myhelloworld in myhelloworld_1.0-1.diff.gz
dpkg-source: warning: newly created empty file 'LICENSE' will not be represented in diff
dpkg-source: warning: the diff modifies the following upstream files: 
 Makefile
 src/myhelloworld.c
dpkg-source: info: use the '3.0 (quilt)' format to have separate and documented changes to upstream files, see dpkg-source(1)
dpkg-source: info: building myhelloworld in myhelloworld_1.0-1.dsc
 debian/rules build
dh build  
   dh_update_autotools_config
   dh_autoreconf
   dh_auto_configure
   dh_auto_build
        make -j12 "INSTALL=install --strip-program=true"
make[1]: Entering directory '/home/ep/sandbox/myhelloworld-1.0'
cc -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
make[1]: Leaving directory '/home/ep/sandbox/myhelloworld-1.0'
   dh_auto_test
   create-stamp debian/debhelper-build-stamp
 fakeroot debian/rules binary
dh binary  
   dh_testroot
   dh_prep
   debian/rules override_dh_auto_install
make[1]: Entering directory '/home/ep/sandbox/myhelloworld-1.0'
dh_auto_install -- prefix=/usr/local/bin
        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
make[2]: Entering directory '/home/ep/sandbox/myhelloworld-1.0'
install -D src/myhelloworld \
        /home/ep/sandbox/myhelloworld-1.0/debian/myhelloworld/usr/local/bin/myhelloworld
make[2]: Leaving directory '/home/ep/sandbox/myhelloworld-1.0'
make[1]: Leaving directory '/home/ep/sandbox/myhelloworld-1.0'
   dh_installdocs
   dh_installchangelogs
   dh_perl
   dh_usrlocal
dh_usrlocal: error: debian/myhelloworld/usr/local/bin/myhelloworld is not a directory
make: *** [debian/rules:9: binary] Error 25
dpkg-buildpackage: error: fakeroot debian/rules binary subprocess returned exit status 2
debuild: fatal error at line 1182:
dpkg-buildpackage -us -uc -ui failed


答案1

不允许包裹发送文件/usr/local,仅目录,这是由 强制执行的dh_usrlocal

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

override_dh_auto_install:
        dh_auto_install -- prefix=/usr/bin

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

override_dh_usrlocal:

请注意,前缀通常被理解为放置各种目录的“根”,因此您可以

prefix = /usr/local


install: src/myhelloworld
        install -D src/myhelloworld \
            $(DESTDIR)$(prefix)/bin/myhelloworld

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

(你的 中有一个轻微的错字Makefile,应该是 $(LDFLAGS),而不是$(LDCFLAGS)。)

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

相关内容