1 |
Thomas Sachau schrieb: |
2 |
> Tomáš Chvátal schrieb: |
3 |
>> Start collecting ideas for EAPI5. |
4 |
> |
5 |
> 1) USE-flag based support to cross-compile packages (mostly implemented in multilib-portage) |
6 |
|
7 |
let me extend this a bit, first the reasoning behind it: |
8 |
|
9 |
|
10 |
For amd64 users, there is sometimes the issue, that they need 32bit libs for certain packages (e.g. |
11 |
wine or many binary-only packages). Currently, they only get them prepackaged in binary form with |
12 |
the emul-linux-x86-* packages. But those packages have a few issues (list does not have to be complete): |
13 |
|
14 |
-they only contain a limited set of 32bit packages |
15 |
-they are precompiled, so the user cannot define his own flags |
16 |
-they have to be manually maintained and updated |
17 |
|
18 |
|
19 |
So the idea was to add the ability to compile 32bit packages with support from the package manager, |
20 |
so there is no need for additional packages to maintain. After this was originally implemented, it |
21 |
was further extended to allow cross-compilation for other targets, not only limited to 32bit packages. |
22 |
|
23 |
|
24 |
The basic way, how this should work: |
25 |
|
26 |
First, there is the check, if the current setup is prepared for cross-compilation, for this, the |
27 |
content of the MULTILIB_ABIS var is checked. If it has more than 1 (space seperated) value, those |
28 |
values are taken and converted into USE flags in the format of multilib_abi_$ABI. |
29 |
In the case of current amd64 multilib profile, which i will take as base for my examples, this means |
30 |
2 additional USE flags: multilib_abi_amd64 and multilib_abi_x86. |
31 |
Those USE flags are internally USE_EXPANDed, so the output after the normal USE flags is in the form |
32 |
of this: MULTILIB_ABI="amd64 -x86" |
33 |
This way, the user is able to define the target ABIs for each package independently from global |
34 |
settings. |
35 |
During dependency calculation, every dependency gets additional USE deps for every target ABI, in |
36 |
this example: category/package[multilib_abi_amd64?,multilib_abi_x86?]. |
37 |
This ensures, that the required dependencies also have the needed 32bit libs/binaries for the |
38 |
requested package. |
39 |
Before the pkg_setup phase is executed, the environment is setup for the first target ABI (in this |
40 |
example: amd64), to make it short, i will just copy the current code from multilib-portage for this: |
41 |
|
42 |
> # Set the CHOST native first so that we pick up the native |
43 |
> # toolchain and not a cross-compiler by accident #202811. |
44 |
> export CHOST=$(get_abi_var CHOST ${DEFAULT_ABI}) |
45 |
> export AS="$(tc-getPROG AS as)" |
46 |
> export CC="$(tc-getPROG CC gcc)" |
47 |
> export CXX="$(tc-getPROG CXX g++)" |
48 |
> export FC="$(tc-getPROG FC gfortran)" |
49 |
> export CHOST=$(get_abi_var CHOST $1) |
50 |
> export CBUILD=$(get_abi_var CHOST $1) |
51 |
> export CDEFINE="$(get_abi_var CDEFINE $1)" |
52 |
> export CCASFLAGS="${CCASFLAGS:-${CFLAGS}} $(get_abi_var CFLAGS)" |
53 |
> export CFLAGS="${CFLAGS} $(get_abi_var CFLAGS)" |
54 |
> export CPPFLAGS="${CPPFLAGS} $(get_abi_var CPPFLAGS)" |
55 |
> export CXXFLAGS="${CXXFLAGS} $(get_abi_var CFLAGS)" |
56 |
> export FCFLAGS="${FCFLAGS} $(get_abi_var CFLAGS)" |
57 |
> export FFLAGS="${FFLAGS} $(get_abi_var CFLAGS)" |
58 |
> export ASFLAGS="${ASFLAGS} $(get_abi_var ASFLAGS)" |
59 |
> export LDFLAGS="${LDFLAGS} $(get_abi_var CFLAGS)" |
60 |
> local LIBDIR=$(get_abi_var LIBDIR $1) |
61 |
> export PKG_CONFIG_PATH="/usr/${LIBDIR}/pkgconfig" |
62 |
> if [[ "${ABI}" != "${DEFAULT_ABI}" ]]; then |
63 |
> [[ -z ${CCACHE_DIR} ]] || export CCACHE_DIR=${CCACHE_DIR}/${ABI} |
64 |
> fi |
65 |
|
66 |
After this, all phases until after src_install are executed as usual. |
67 |
|
68 |
After src_install, there are some checks: |
69 |
If there is another target ABI, the install dir is checked for possible abi-specific files (headers, |
70 |
libs, binaries). |
71 |
If both conditions are true, the current install dir is saved in a different location, everything |
72 |
cleaned up and the package manager starts again at the preparation step for the target ABI before |
73 |
pkg_setup. This is done until all target ABIs have been done. |
74 |
|
75 |
Now comes the merging step: For each target ABI, the installed files get moved back to the original |
76 |
install location with 2 exceptions: |
77 |
-if the headers differ between the target ABIs, they get installed into abi-specific subdirectories |
78 |
and the original header file becomes a wrapper file, which includes the abi-specific header file |
79 |
depending on the current environenment. |
80 |
-if there are binaries (and this step is not restricted), those get moved into their original |
81 |
location, but with an abi-specific appendix, the original file is replaced by a symlink to an |
82 |
abi-wrapper, which executes the abi-specific binary depending on the current environment. |
83 |
|
84 |
After this is done, following phases are executed. the pkg_* phases after src_install are looped |
85 |
over all currently enabled target ABIs. This ensures, that abi-specific commands are executed for |
86 |
every target ABI. |
87 |
|
88 |
Differences, options and other things with current multilib-portage implementation: |
89 |
|
90 |
The binary wrapping in current multilib-portage is only happening, if the package is defined in the |
91 |
MULTILIB_BINARIES var to avoid the modification of existing ebuilds. For my proposal, this wrapping |
92 |
should happen by default, unless this is restricted in the ebuild, e.g. by RESTRICT="multilib-binaries". |
93 |
|
94 |
Another usefull thing not currently enabled in multilib-portage: Instead of having the USE flag for |
95 |
the current platform internally enabled (in this example, USE=amd64), the target ABI should be the |
96 |
currently active internal USE flag (in this example, USE=x86 during compilation for x86). This |
97 |
allows for abi-specific changes and would also allow to install abi-specific files for binary |
98 |
packages (if there is a binary package for the target ABI and a loop over all enabled target ABIs in |
99 |
pkg_fetch done). |
100 |
|
101 |
Since none of this directly affects the ebuilds, the package manager can optionally enable this for |
102 |
all packages (like multilib-portage does currently), the main point, why this needs to go into an |
103 |
EAPI is the ability to require a package to provide files for a different target ABI (e.g. packages |
104 |
for amd64 could directly depend on category/package[multilib_abi_x86], if they require the 32bit |
105 |
libs of this package). |
106 |
|
107 |
|
108 |
I hope, this can be at least the base (together with the existing implementation in |
109 |
multilib-portage) for a spec to get cross-compile support into EAPI-5. |
110 |
|
111 |
For reference: |
112 |
-the code of current multilib-portage is in the portage repository on git.overlays.gentoo.org inside |
113 |
the multilib branch |
114 |
-an ebuild to install multilib-portage is in the multilib overlay in the portage-multilib branch |
115 |
(current version in there is 2.2.0_alpha55-r1, i need to merge the most recent changes of portage, |
116 |
so it might sometimes be a bit behind the latest portage version) |
117 |
-a minimal stage4 with multilib-portage (also already some months old) can be found in a qemu image |
118 |
on our distfiles mirrors inside experimental/amd64/qemu/, it is called |
119 |
multilib-amd64-qemu-2010-12-08.img.lzma |