Gentoo Archives: gentoo-pms

From: James Le Cuirot <chewi@g.o>
To: gentoo-pms@l.g.o
Subject: Re: [gentoo-pms] [PATCH] Correct the definition of ESYSROOT as EPREFIX isn't always applicable
Date: Wed, 12 Jun 2019 22:05:47
Message-Id: 20190612230533.5481f211@symphony.aura-online.co.uk
In Reply to: Re: [gentoo-pms] [PATCH] Correct the definition of ESYSROOT as EPREFIX isn't always applicable by "Michał Górny"
1 On Sun, 02 Jun 2019 08:10:34 +0200
2 Michał Górny <mgorny@g.o> wrote:
3
4 > On Sat, 2019-06-01 at 23:29 +0100, James Le Cuirot wrote:
5 > > Unfortunately my conception of ESYSROOT was a little short-sighted. It
6 > > was previously defined as SYSROOT + EPREFIX but if SYSROOT does not
7 > > equal ROOT then EPREFIX does not make sense in this context. Consider
8 > > a more concrete example:
9 > >
10 >
11 > Once again, you are missing the point that e.g. pkg-config files will
12 > have EPREFIX hardcoded.
13
14 I had remembered that you objected to this but I had forgotten why. I
15 said at the time that I believed your concerns were misplaced and that
16 hasn't changed but I wanted to actually try it out to prove it to
17 myself as much as you.
18
19 If EPREFIX is set in the environment by the user, it only applies to
20 ROOT. If you're emerging a bunch of packages in a single run with some
21 going to / and some going to ROOT, Portage will adjust EPREFIX for each
22 destination and hardcode the correct prefix value into the .pc files
23 accordingly.
24
25 Up till now, we have said that you can set SYSROOT to either match / or
26 ROOT. The former is typically used for native while the latter is
27 typically used for cross. Whether you're building against / or ROOT,
28 the .pc files picked up from each will have the prefix hardcoded for
29 each. This is exactly what we want!
30
31 It was surprisingly hard to find a simple package that worked under
32 prefix and located a header via pkg-config that otherwise would not be
33 found without an -I flag. After a long search, the package I eventually
34 settled on was your very own x11-libs/libtinynotify, which uses
35 pkg-config to query dbus-1.
36
37 My setup is as follows:
38 BROOT=/home/chewi/prefix
39 ROOT=/home/chewi/myroot
40 EPREFIX=/myprefix
41
42 Therefore, Portage sets:
43 EROOT=/home/chewi/myroot/myprefix
44
45 I wanted to try this with both SYSROOT=/ and SYSROOT=${ROOT}. Without
46 my associated changes to Portage, the former actually blows up.
47
48 Calculating dependencies... done!
49 Traceback (most recent call last):
50 File "/home/chewi/prefix/usr/lib/python-exec/python3.6/emerge", line 53, in <module>
51 retval = emerge_main()
52 File "/home/chewi/prefix/usr/lib64/python3.6/site-packages/_emerge/main.py", line 1289, in emerge_main
53 return run_action(emerge_config)
54 File "/home/chewi/prefix/usr/lib64/python3.6/site-packages/_emerge/actions.py", line 3325, in run_action
55 retval = action_build(emerge_config, spinner=spinner)
56 ...
57 File "/home/chewi/prefix/usr/lib64/python3.6/site-packages/_emerge/depgraph.py", line 4722, in _select_atoms_highest_available
58 pkgsettings = self._frozen_config.pkgsettings[root]
59 KeyError: '/myprefix/'
60
61 This error precisely highlights the problem with PMS as it stands now.
62 If SYSROOT=/ and EPREFIX=/myprefix then SYSROOT + EPREFIX is
63 also /myprefix, which Portage hasn't been told about because it doesn't
64 even exist. It only exists under /home/chewi/myroot.
65
66 With my changes in place, things are resolved as follows. dbus is
67 installed in both locations because libtinynotify is only EAPI 6.
68
69 [ebuild N ] sys-apps/dbus-1.12.14 to /home/chewi/myroot/myprefix/ USE="-X -debug -doc -elogind (-selinux) -static-libs -systemd -test -user-session"
70 [ebuild N ] sys-apps/dbus-1.12.14 USE="-X -debug -doc -elogind (-selinux) -static-libs -systemd -test -user-session"
71 [ebuild N ] x11-libs/libtinynotify-0.2.1 to /home/chewi/myroot/myprefix/ USE="-debug -doc -static-libs"
72
73 Updating libtinynotify to EAPI 7 while building with SYSROOT=${ROOT}
74 changes the output to this.
75
76 [ebuild N ] sys-apps/dbus-1.12.14 to /home/chewi/myroot/myprefix/ USE="-X -debug -doc -elogind (-selinux) -static-libs -systemd -test -user-session"
77 [ebuild N ] x11-libs/libtinynotify-0.2.1 to /home/chewi/myroot/myprefix/ USE="-debug -doc -static-libs"
78
79 In all cases, both packages build successfully but pkg-config adds
80 -I/home/chewi/prefix/usr/include/dbus-1.0 regardless of SYSROOT. This
81 is because native builds like this have no special SYSROOT handling for
82 pkg-config. This handling exists in crossdev's cross-pkg-config
83 for cross builds but even that currently has no prefix support
84 whatsoever. I therefore have some heavy modifications pending for
85 cross-pkg-config.
86
87 It is debatable whether we should apply SYSROOT handling to pkg-config
88 all the time. While we do technically allow SYSROOT!=/ for native
89 builds, this is so problematic in general that we probably shouldn't go
90 out of our way to support it. We don't need to do anything for the
91 SYSROOT=/ case because the default behaviour is what we want.
92
93 In my example, I'm not cross-compiling so I could force the use of
94 cross-pkg-config to make it work but to keep things simple, I have
95 written a short bashrc that does the equivalent. This file is placed
96 in /home/chewi/myroot/myprefix/etc/portage because we only want it to
97 apply when building packages for ROOT. We therefore need to set
98 PORTAGE_CONFIGROOT so that it actually gets used.
99
100 if [[ -n ${SYSROOT%/} ]]; then
101 myprefix=${EPREFIX%/}
102 else
103 myprefix=${PORTAGE_OVERRIDE_EPREFIX%/}
104 fi
105
106 unset PKG_CONFIG_PATH
107 export PKG_CONFIG_SYSTEM_LIBRARY_PATH="${myprefix}/usr/lib64:${myprefix}/lib64"
108 export PKG_CONFIG_SYSROOT_DIR="${SYSROOT}"
109 export PKG_CONFIG_LIBDIR="${SYSROOT}${myprefix}/usr/lib64/pkgconfig:${SYSROOT}${myprefix}/usr/share/pkgconfig"
110
111 In cross-pkg-config, I check ESYSROOT first and determine the prefix by
112 chopping off SYSROOT. This allows us to support a distinct SYSROOT and
113 is necessary because we didn't define a variable for SYSROOT's prefix.
114
115 For EAPIs before 7, I fall back to something along the lines of the
116 above. Using PORTAGE_OVERRIDE_EPREFIX works but it's not ideal so I may
117 just bake the value into cross-pkg-config when crossdev is installed.
118
119 And the result? It works as expected. Regardless of whether
120 libtinynotify uses EAPI 6 or 7, the build output includes the following:
121
122 With SYSROOT=/ :
123
124 libtool: compile: x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/home/chewi/prefix/usr/include/dbus-1.0 -I/home/chewi/prefix/usr/lib64/dbus-1.0/include -O2 -pipe -O2 -pipe -c lib/common.c -fPIC -DPIC -o .libs/libtinynotify_la-common.o
125
126 With SYSROOT=${ROOT} :
127
128 libtool: compile: x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/home/chewi/myroot/myprefix/usr/include/dbus-1.0 -I/home/chewi/myroot/myprefix/usr/lib64/dbus-1.0/include -O2 -pipe -O2 -pipe -c lib/common.c -fPIC -DPIC -o .libs/libtinynotify_la-common.o
129
130 For completeness, I decided to try the distinct SYSROOT case as well
131 with SYSROOT=/home/chewi/mysysroot. The short bashrc above does not
132 support this but the revised cross-pkg-config does. You would typically
133 need the libc and kernel headers installed to this SYSROOT first but I
134 haven't defined CC="x86_64-pc-linux-gnu-gcc --sysroot=${ESYSROOT}" like
135 I normally do under cross-boss. Only pkg-config is being affected here,
136 which is sufficient for this demonstration. And it works!
137
138 libtool: compile: x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/home/chewi/mysysroot/usr/include/dbus-1.0 -I/home/chewi/mysysroot/usr/lib64/dbus-1.0/include -O2 -pipe -O2 -pipe -c lib/common.c -fPIC -DPIC -o .libs/libtinynotify_la-common.o
139
140 Distinct SYSROOTs are not something I expect to be used frequently but
141 they are initially needed when cross-building a brand new system into
142 an empty directory, which is exactly what cross-boss does.
143
144 I hope this makes sense now.
145
146 --
147 James Le Cuirot (chewi)
148 Gentoo Linux Developer