mate-desktop / mate-wayland-session

GNU General Public License v2.0
31 stars 5 forks source link

Cannot install in Debian #2

Open Sunderland93 opened 8 months ago

Sunderland93 commented 8 months ago

Hello. I'm trying to create a deb package with mate-wayland-session, but while creating it I get an error:

   create-stamp debian/debhelper-build-stamp
   dh_prep
   dh_auto_install --destdir=debian/mate-wayland-session/
        make -j12 install DESTDIR=/media/DATA/Repos/mate-wayland-session-1.27\~git20231222/debian/mate-wayland-session AM_UPDATE_INFO_DIR=no
make[1]: вход в каталог «/media/DATA/Repos/mate-wayland-session-1.27~git20231222»
Making install in session
make[2]: вход в каталог «/media/DATA/Repos/mate-wayland-session-1.27~git20231222/session»
make[3]: вход в каталог «/media/DATA/Repos/mate-wayland-session-1.27~git20231222/session»
make[3]: Цель «install-exec-am» не требует выполнения команд.
mkdir -p /usr/bin
mkdir -p /usr/share/wayland-sessions
cp  mate-wayland.sh /usr/bin/mate-wayland.sh
cp: невозможно создать обычный файл '/usr/bin/mate-wayland.sh': Отказано в доступе

Here is my debian/rules:

#!/usr/bin/make -f

# See FEATURE AREAS in dpkg-buildflags(1).
export DEB_BUILD_MAINT_OPTIONS = hardening=+all

DPKG_EXPORT_BUILDFLAGS = 1
include /usr/share/dpkg/buildflags.mk

%:
    dh $@ --without autoreconf

override_dh_missing:
    dh_missing --fail-missing

override_dh_auto_configure:
    NOCONFIGURE=1 ./autogen.sh
    dh_auto_configure
lukefromdc commented 8 months ago

I tested this on my end, the error I got was a failure to find the changelog file, even though it exists, is in the toplevel directory as expected, and in preparing the package I ran git log with the output redirected to the changelog.

The error I got was dpkg-buildpackage: error: cannot open file debian/changelog: No such file or directory Note that the MATE source packages provide ChangeLog but we are looking for debian/changelog which becomes changelog.Debian in the built package

I cannot translate what you got because I boycott Google for privacy reasons.

I didn't see this myself because I have always used Checkinstall to build Debian packages in autotools, fetching the built directories from /var/tmp and copying them to a directory including a manually edited DEBIAN/control file.

Sunderland93 commented 8 months ago

I cannot translate what you got because I boycott Google for privacy reasons.

mkdir -p /usr/bin mkdir -p /usr/share/wayland-sessions cp mate-wayland.sh /usr/bin/mate-wayland.sh cp: cannot create regular file '/usr/bin/mate-wayland.sh': Permission denied

lukefromdc commented 8 months ago

That looks like an attempt to copy the files directly into the root directory instead of into the package, as though running make install without sudo as a normal user. I really don't know a lot about how the normal Debian packaging system works though and am not on their team.

Turns out my normal DEBIAN/control files are completely invalid for dpkg-buildpackage I get error after error and never reach the build process, I see you have.

last error I got was


dh clean --without autoreconf
dh: error: Compatibility levels before 7 are no longer supported (level 1 requested)
make: *** [debian/rules:10: clean] Error 255
dpkg-buildpackage: error: fakeroot debian/rules clean subprocess returned exit status 2
lukefromdc commented 8 months ago

A quick way to build an installable Debian package (not one Debian could offer in their repos though) is this:

1: configure and build (build is a no-op for this package) with meson, do not install yet

2: create a directory with the desired name of the package. I am using /home/luke/Desktop/Development/MATE_Development_Work/mate-wayland-session_1.27.0+git20231222-1luke1_all for today's build as an example

3: create a DEBIAN/control file for the package and include it in the directory you just created. Also add this DEBIAN/postinst file:

#!/bin/sh
# 
glib-compile-schemas /usr/share/glib-2.0/schemas

so installing the package anywhere also recompiles the schemsa

4: Change ownership of this directory to root as a precaution against dpkg installing the files with normal user ownership. No idea if that still happens but I did see this in 2015.

5: For the directrory name I just listed, I "install" to the directory which will become the Debian package's contents with sudo DISTDIR=/home/luke/Desktop/Development/MATE_Development_Work/mate-wayland-session_1.27.0+git20231222-1luke1_all ninja -C build install That redirects all files made by installation to the directory given, the postinstall script runs as normal.

6: I then add /usr/share/doc/mate-wayland-session and put the changlogs and other docs in there, this is optional for a local install

7: Run sudo dpkg -b on the directory you just made, a Debian package that can be installed with sudo dpkg -i will appear in the parent directory if your DEBIAN/control file is sufficiently valid. If not, fix any errors reported and try again

L-U-T-i commented 6 months ago

It seems installation paths are hardcoded in 'session/Makefile.am', so '--destdir' can not be respected.

I've simply done the following before building - %{buildroot} is a rpmbuild macro:

sed -i 's|\(/etc/mate\)|%{buildroot}\1|g' session/Makefile.am
sed -i 's|\($(bindir)\)|%{buildroot}\1|g' session/Makefile.am
sed -i 's|\($(datadir)\)|%{buildroot}\1|g' session/Makefile.am

but a general fix ('destdir' path instead of '%{buildroot}') is definitely needed.

Beside of that, I've had to do also the following: sed -i 's|\(AM_INIT_AUTOMAKE(\[.*\)\(\])\)|\1 foreign\2|g' configure.ac as there is README.md instead of README; without AM_INIT_AUTOMAKE[foreign] option, I've got an error:

makefile.am: error: required file './README' not found
autoreconf: automake failed with exit status: 1

and: sed -i '1 i #!%{_bindir}/sh' session/mate-wayland.sh to fix rpmbuild '*** WARNING: ./usr/bin/mate-wayland.sh is executable but has no shebang, removing executable bit'.

Purely "cosmetic", I am doing this as well (to unify naming with other Mate packages), even if absolutely not needed:

mv makefile.am Makefile.am
mv data/makefile.am data/Makefile.am
mv data/mate/makefile.am data/mate/Makefile.am
mv session/makefile.am session/Makefile.am
sed -i 's|makefile|Makefile|g' configure.ac

Everything with: NOCONFIGURE=1 ./autogen.sh following, of course.

lukefromdc commented 6 months ago

Note that session managers (at least SDDM) seem to only look in /usr/share/wayland-sessions for wayland sessions and I think /usr/local cannot be used. The build system is one of my weakest areas here. Will try your suggestions.

As it stands now, built to install to /usr/local will hang on installing the schema, I could code it to not install the schema in that case (would just mean our theme defaults are not applied, nothing more), but I think the session directory has to be hardcoded too.

lukefromdc commented 6 months ago

I renamed README.md to README and applied the cosmetic changes. A lot of this stems from the fact that I know very little about autotools and the documentation is difficult to understand.

For building Debs using autotools I have only known Checkinstall followed by running dpkg -b, on a directory copied from it's results, and in Meson the use of DESTDIR= in ninja -C build install and do not even know how to edit Debian's normal building files to use altered source code. I simply do not know how to configure the official way to build .debs at all.

There is probably no way I can get this into a state distros can use normally by myself. I was able to figure out the actual wayland porting, but I simply do not know packaging at the distro level at all. I need help from others to get this into a state distros can use.

L-U-T-i commented 6 months ago

Thank you for commited changes.

To make it more general (easily changed if it is not rpmbuild packaging with %{buildroot} set), I've changed the following:

%prep
%autosetup %{!?rel_build:-n %{name}-%{commit}} -p1
sed -i 's|\($(bindir)\)|%{buildroot}\1|g' session/Makefile.am
sed -i 's|\($(datadir)\)|%{buildroot}\1|g' session/Makefile.am
%{!?rel_build:NOCONFIGURE=1 ./autogen.sh}
...
%install
%{make_install}

to:

%prep
%autosetup %{!?rel_build:-n %{name}-%{commit}} -p1
sed -i 's|\($(bindir)\)|"$(DESTDIR)\1"|g' session/Makefile.am
sed -i 's|\($(datadir)\)|"$(DESTDIR)\1"|g' session/Makefile.am
%{!?rel_build:NOCONFIGURE=1 ./autogen.sh}
...
%install
%{make_install} DESTDIR="%{buildroot}"

now.

And, I am also changing '/bin/sh' to '/usr/bin/sh':

sed -i 's|#!/bin/sh|#!%{_bindir}/sh|g' *.sh
sed -i 's|#!/bin/sh|#!%{_bindir}/sh|g' session/*.sh

even if it would work also as it is (there is a link '/bin' to '/usr/bin' in RHEL 9...). I think it is a kind of "standard"?

lukefromdc commented 6 months ago

Note that I have never worked with RPMs save by opening them in an archive manager

lukefromdc commented 6 months ago

All of my builds did in fact send the scripts to /usr/bin both in autotools and in meson. I don't know enough about the build system to understand the rest of what you posted at this moment. Never before have I attempted to create an entire package for use by distros as opposed to those customising one machine

L-U-T-i commented 6 months ago

rpmbuild "prepares" files (during the %install phase) within a 'buildroot' directory (you can consider that as a kind of chroot), before they are actually packed into RPM(s).

Normally, rpmbuild process takes care so that everything actually goes smoothly (it kind a changes prefix in install phase - prepend it with a %{buildroot}), but any hardcoded paths are a problem in this case (as those files are not found within a %{buildroot} when they should be actually packed into an RPM).

I have therfore prepend paths for installation part of your 'session/Makefile.am' first with %{buildroot}, what suits for rpmbuild. Now I've prepended it with $(DESTDIR), so if DESTDIR is not set, nothing changes; if it is set to something (as DESTDIR="%{buildroot}" in my case), files are installed there (as expected).

The last part just changes the scripts shebang from #!/bin/sh to #!/usr/bin/sh, what I believe is more standard (as you mention above, "All of my builds did in fact send the scripts to /usr/bin" - and not to /bin).

lukefromdc commented 6 months ago

Feel free to submit a PR for this, especially if you can avoid having to hardcode installation paths. Be aware though that at least some session managers will only look for wayland sessions in /usr/share/wayland, and that the gschema override won't work unless it goes to the same directory the schemas were installed into for everything else.

L-U-T-i commented 6 months ago

I'm sorry, I don't use git at all, and don't even know how to submit a PR (I am just browsing https://github.com and download what I need - usually tar packed release or commit stage, and / or some PR patches...).

As much as I can see in session/Makefile.am, DESTDIR is actually used in install part of the build process only (and not in the compiling or linking phase, what could probably make a mess). So, If you know what you are doing (or, you simply don't set / use a DESTDIR variable at all), everything goes as now (without this patch - into /usr/share/wayland ... unless one's prefix is not the usual /usr, of course...). If however you need to temporary change the destinations for just the installation phase (as in rpmbuild process as above), you have a possibility to simply do it this way. Rpmbuild always takes care that upon a pakage installation those files land in a normal prefix (/usr) and not in the temporary one (%{buildroot}/usr - that one is used only in a package building phase, and most probably doesn't even exist on a destination system...).

In any case, it might be worth to mention in the build instructions that you can simply change an installation prefix during the package build process setting the DESTDIR (make install DESTDIR=...) if needed (as in rpmbuild), but that you are definitely advised not to mess with it if you build/install directly on a target system (as there file(s) need to land in /usr/share/wayland).

lukefromdc commented 5 months ago

Build system has received a great many changes to support making tarballs with make distcheck so please test again