[opensuse-buildservice] Cross compilation dependency handling
Hi, One of the discussion points about my SB2-OBS patch is that we ought to work towards a common strategy for denoting these special kind of dependencies in prjconf instead of using "SB2install" "CBinstall" etc. Daniel Gollub suggested that we work with N amount of 'sysroots' and N rpm databases and I tend to agree. Right now in SB2 I distinguish between host (/) and target /target, but it might be more flexible to do with N targets instead. The question is of course, can we effectively work with multiple dependency trees (maybe even across schedulers?) within the current code and how do we do it best? Adrian suggested something like Preinstall($hostarch) to indicate that this needs to be preinstalled on host architecture. My suggestion would be perhaps to indicate through configuration where to put things, for example, Roots: host=/ armv7l=/opt/cross/armv7l, etc, so we can do dynamic labeling and telling what location on the build filesystem things should go in. What are your thoughts? BR Carsten Munk -- To unsubscribe, e-mail: opensuse-buildservice+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-buildservice+owner@opensuse.org
Am Donnerstag, 16. Februar 2012, 10:43:01 schrieb Carsten Munk:
Hi,
One of the discussion points about my SB2-OBS patch is that we ought to work towards a common strategy for denoting these special kind of dependencies in prjconf instead of using "SB2install" "CBinstall" etc.
Daniel Gollub suggested that we work with N amount of 'sysroots' and N rpm databases and I tend to agree. Right now in SB2 I distinguish between host (/) and target /target, but it might be more flexible to do with N targets instead.
The question is of course, can we effectively work with multiple dependency trees (maybe even across schedulers?) within the current code and how do we do it best?
Adrian suggested something like Preinstall($hostarch) to indicate that this needs to be preinstalled on host architecture.
Thinking again about it, specify an arch here makes not much sense. Better something like this in spec files: BuildRequire(host): gcc BuildRequire(target): libqt4-devel Since this is not supported by rpm yet, we would need to have something like #!BuildRequire(host): gcc #!BuildRequire(target): libqt4-devel So when a BuildRequire: gcc appears later in the spec file (for plain rpm non-cross building), OBS can see that it has it already, but it knows already for which architecture it needs it. The prjconf Preinstall, Support and Require lines could also support the (host) and (target) extensions.
My suggestion would be perhaps to indicate through configuration where to put things, for example, Roots: host=/ armv7l=/opt/cross/armv7l, etc, so we can do dynamic labeling and telling what location on the build filesystem things should go in.
Yes, similar to Hostarch: directive, we could add a Targetpath: directive... just thinking loud. adrian
What are your thoughts?
BR Carsten Munk -- Adrian Schroeter SUSE Linux Products GmbH email: adrian@suse.de
Hi Carsten, Hi Adrian, On Thursday, February 16, 2012 11:01:15 AM Adrian Schröter wrote:
Am Donnerstag, 16. Februar 2012, 10:43:01 schrieb Carsten Munk: [...]
Daniel Gollub suggested that we work with N amount of 'sysroots' and N rpm databases and I tend to agree. Right now in SB2 I distinguish between host (/) and target /target, but it might be more flexible to do with N targets instead.
We started last week finally to do some prototyping of this idea. Added Christian and Uwe into the loop, since booth of them implemented most of the stuff I'm mentioning here. This is a "brief" (sorry, at least I tried to keep it brief) what we have already in place and is working to some point (we have no build results yet). Scheduler and Worker modification by Christian: * Add new parameter to prjconf for additional architectures New parameter 'AdditionalArch' added to projectconfiguration (prjconf). This parameter identifies additional architectures with its sysroot that should be downloaded during build preparation. AdditionalArch: <arch> <sysroot> In the prjconf we put something like this: ---8<-- [...] Required: gcc gcc%{gcc_version} glibc rpm tar patch %ifarch armv5el armv7l Hostarch: x86_64 %obs_crossbuild 1 # not yet used AdditionalArch: x86_64 / # actually not required, IIR AdditionalArch: armv7l /sysroot/armv7l AdditionalArch: armv5el /sysroot/armv5el Required(target): tar [...] --->8---- * determine packages used in hostsystem or in target-sysroot To determine which package has to be installed where, in the host system or in a sysroot for a crossbuild. Therefor the XML for the buildinfo got a new field for packages. 'neededbyhost' has to be set to 1 if a package has to be installed in the host system. If this parameter is not set or 0 the package will be downloaded for the architecture the buildjob is for and for all additional architectures into their sysroots. With the example prjconf from above, the scheduler sends an enhanced buildjob file which looks something like this: ---8<--- <buildinfo project="home:Admin" repository="openSUSE_Factory_ARM_standard" package="foo" srcserver="http://b1-systems.de:5352" reposerver="http://b1-systems.de:5252"> <job>home:Admin::openSUSE_Factory_ARM_standard::foo-6763ac6ae31fbc1a89ed98c53d443ce8</job> <arch>armv7l</arch> <hostarch>x86_64</hostarch> <additional_archs arch="x86_64" sysroot="/" /> <!--- actually not required, IIRC ---> <additional_archs arch="armv7l" sysroot="/sysroot/armv7l" /> <additional_archs arch="armv5el" sysroot="/sysroot/armv5el" /> [...] <bdep name="aaa_base" preinstall="1" runscripts="1" notmeta="1" neededbyhost="1" /> [...] <bdep name="tar" preinstall="1" neededbyhost="1" /> [...] <bdep name="libsepol1" vminstall="1" target_arch="x86_64" /> <bdep name="libblkid1" vminstall="1" notmeta="1" target_arch="x86_64" /> <bdep name="libuuid1" vminstall="1" notmeta="1" target_arch="x86_64" /> <bdep name="gcc" /> <bdep name="gcc46" /> <bdep name="patch" /> <bdep name="cpp" /> [...] <bdep name="tar" /> [...] <path project="home:Admin" repository="openSUSE_Factory_ARM_standard" server="http://srsyy.b1-systems.de:5252" /> <path project="openSUSE:Factory:ARM" repository="standard" server="http://srsyy.b1-systems.de:5252" /> </buildinfo> --->8--- * Adjustments on the worker The worker is now able to download packages for N-architectures and put them into separate directories and RPMlists. Both are given to the buid script using the new parameters --rpmlist-target. Also it sets --target accordingly to the architecture the job does the build for. srsyy:/var/cache/obs/worker/root_1 # ls -1 .build*rpmlist .build.armv7l.rpmlist .build.armv5el.rpmlist .build.rpmlist The new "Required(target):" allows mutliple occurences of the same package-name (e.g. "tar") to serve hostarch and targets with the same dependency (but different target) -> this will result in a tar package for the hostarch x86_64 and the targets armvl and armv5el - in seperated directories: srsyy:/var/cache/obs/worker/root_1 # find -name tar.rpm ./.armv5el.pkgs/tar.rpm ./.armv7l.pkgs/tar.rpm ./.pkgs/tar.rpm Currently we only assign preinstall: vminstall: to the hostarch rpmlist. All other packages get assigend to the target rpmlists. So the hostarch is a minimal set to bootup a VM or switch into a chroot. Following obs-build script modifications got introduced so far by Uwe: * Add initialization of separate build root for cross compiling targets The build script from obs-build has been enhanced, to setup additional build root environments. To achieve this, a new parameter --rpmlist-target has been introduced for setting up additional build environments. Currently the name of the rpmlist file is taken as architecture name is created at $BUILD_ROOT/sys-root/<arch>. In the build script a new function setup_sys_root() has been added, which uses the build_initscript from obs-build to setup additional build enviroments. The build_initscript has been enhanced to allow the setup of addtional environments underneath the host target environment. A new parameter --root was introduced, which overwrites the ROOT_BUILD environment variable. (We are currently discussing if we can avoid the introduction of this --root parameter) * Add cross build command A new function cross_build() has been introduced in the build script from obs-build. It is responsible for executing the commands to cross build a package for the given architecture. Right now the functionality is copied from the build commands for the host architecture, and have to be adapted for necessary commands for cross build a package. * Add initialization of rpm database for a cross build environment The build script from obs-build will be enhanced to allow the initialization of rpm database in a cross build environment. (Instead of chroot $BUILD_ROOT rpm --init-db... we want to call the hostarch rpm binary without chroot use) There are still places where we need to touch code in init_buildsystem or build script to not make use of chroot and instead call hostarch "toolchain" to setup the buildenv. We have not reached the final "rpmbuild" call yet. That's the reason why we have no build results yet. (this cmdline is from a test without armv5el - just armv7l) /bin/bash /var/run/obs/worker/1/build/build --root /var/cache/obs/worker/root_1 --clean --changelog --oldpackages /var/cache/obs/worker/root_1/.build.oldpackages --norootforbuild --baselibs-internal --lint --dist /var/cache/obs/worker/root_1/.build.config --rpmlist /var/cache/obs/worker/root_1/.build.rpmlist --rpmlist-target /var/cache/obs/worker/root_1/.build.armv7l.rpmlist --target armv7l -- logfile /var/cache/obs/worker/root_1/.build.log --release 15.1 --arch armv7l --jobs 1 --reason Building foo for project 'home:Admin' repository 'openSUSE_Factory_ARM_standard' arch 'armv7l' srcmd5 '6763ac6ae31fbc1a89ed98c53d443ce8' --disturl obs://srsyy.b1-systems.de/home:Admin/openSUSE_Factory_ARM_standard/6763ac6ae31fbc1a89ed98c53d443ce8-foo /var/cache/obs/worker/root_1/.build-srcdir/foo.spec * --rpmlist-target /var/cache/obs/worker/root_1/.build.armv7l.rpmlist # --rpmlist-target can be invovked multiple times # --rpmlist is used for hostarch * --target armv7l # sets the ABUILD_TARGET ... even if we support N-Target-Sysroots actual build happens only for one target We are think of introducing --crossbuild to indicate that we are doing no native-crossbuild. The target-sysroot-pathes got not yet passed along to the build script. But we plan to do so.
The question is of course, can we effectively work with multiple dependency trees (maybe even across schedulers?) within the current code and how do we do it best?
Our prototype managed to assemble a buildjob which a patched worker understands and retrieves RPMs from different trees. But all this requries that those RPMs from the different architectures are already build and available. We still need to introduce something that the scheduler schedules the cross build job only if all cross-target dependencies are solved. So there is the need that the scheduler check the meta-data/status of the other architectures - if the all cross dependencies are ready. For example: if a pre-install: for the Hostarch x86_64 is failing/missing, the armv7l scheduler would still schedule the buildjob.
Adrian suggested something like Preinstall($hostarch) to indicate that this needs to be preinstalled on host architecture.
I guess introducing "preinstall($hostarch)" is harder then "preinstall(host)". Working with our current prototype it really looks like you do not really need to care about what your hostarch is. You just need to distinguish between: is it a package for the host or for one of the targets? So we currently follow this approach: Imagine you need have as Hostarch: x86_64 (<hostarch />) and need additionally those Targets: armv7l, i586, armv5el. (<additional_archs />) Your primary build target (to build a package for) is: armv7l (<arch />) - preinstall: / vminstall: packages will only be installed for the hostarch. - all other build dependencies will be installed for each additional_arch - depending on the BuildRequires in your spec-file. All this will result in a $BUILD_ROOT which looks something like this: $BUILD_ROOT/ <- stuffed with set of preinstall: / vminstall: packages $BUILD_ROOT/sysroot-armv7l/ <- no preinstall/vminstall, but all other package dependencies for armv7l installed in a seperated package database $BUILD_ROOT/sysroot-armv5el/ <- no preinstall/vminstall, but all other package dependencies for armv5el installed in a seperated package database $BUILD_ROOT/sysroot-i586/ <- no preinstall/vminstall, but all other package dependencies for i586 installed in a seperated package database What is not covered yet is to introduce special dependencies for crossbuild only. For testing we introduced this one: Required(target): If you run a crossbuild, those required packages will only get installed in your target-sysroots. For non-crossbuilds not.
Thinking again about it, specify an arch here makes not much sense.
Better something like this in spec files:
BuildRequire(host): gcc BuildRequire(target): libqt4-devel
Since this is not supported by rpm yet, we would need to have something like
#!BuildRequire(host): gcc #!BuildRequire(target): libqt4-devel
So when a
BuildRequire: gcc
appears later in the spec file (for plain rpm non-cross building), OBS can see that it has it already, but it knows already for which architecture it needs it.
I thought about doing this in another way or even provide something additionally. Instead of putting special crossbuild dependencies in each spec files (by default), use some kind of Substitute(host): / Substitute(target): / Required(target): / Required(host): combination. Something like this: Substitute(target): gcc %{crosstag}gcc -> Drops gcc from the target dependency list and will replace it with a dependency of %{crosstag}gcc in the hostarch tree. Substitute(crossdep): libqt4-devel -> if libqt4-devel shows up in the build-depenency of a target (in a crossbuild), libqt4-devel gets a "cross dependency": it gets additionally a dependency for the hostarch. (e.g. if you want to use pre-processors and run them with native performance, but need target specific headers, static libraries, ...)
The prjconf Preinstall, Support and Require lines could also support the (host) and (target) extensions.
Right. So far we only needed Required(target). But very likely we need more of them while keep working on that.
My suggestion would be perhaps to indicate through configuration where to put things, for example, Roots: host=/ armv7l=/opt/cross/armv7l, etc, so we can do dynamic labeling and telling what location on the build filesystem things should go in.
Yes, similar to Hostarch: directive, we could add a Targetpath: directive...
What do you think about the "AdditionalArch: $ARCH $TARGETPATH" directive? Or should we change this to something else? Btw, our git branches can be found here: https://github.com/b1-systems/obs-build/commits/crossbuild https://github.com/b1-systems/open-build-service/commits/crossbuild Best Regards, Daniel -- Daniel Gollub Linux Consultant & Developer Tel.: +49-160 47 73 970 Mail: gollub@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg / http://www.b1-systems.de GF: Ralph Dehner / Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 - -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi, just one point to correct here.. On 02/23/2012 07:21 PM, Daniel Gollub wrote:
Hi Carsten, Hi Adrian,
On Thursday, February 16, 2012 11:01:15 AM Adrian Schröter wrote:
Am Donnerstag, 16. Februar 2012, 10:43:01 schrieb Carsten Munk: [...]
Daniel Gollub suggested that we work with N amount of 'sysroots' and N rpm databases and I tend to agree. Right now in SB2 I distinguish between host (/) and target /target, but it might be more flexible to do with N targets instead.
We started last week finally to do some prototyping of this idea.
* determine packages used in hostsystem or in target-sysroot
To determine which package has to be installed where, in the host system or in a sysroot for a crossbuild. Therefor the XML for the buildinfo got a new field for packages. 'neededbyhost' has to be set to 1 if a package has to be installed in the host system. If this parameter is not set or 0 the package will be downloaded for the architecture the buildjob is for and for all additional architectures into their sysroots.
With the example prjconf from above, the scheduler sends an enhanced buildjob file which looks something like this:
---8<--- <buildinfo project="home:Admin" repository="openSUSE_Factory_ARM_standard" package="foo" srcserver="http://b1-systems.de:5352" reposerver="http://b1-systems.de:5252"> <job>home:Admin::openSUSE_Factory_ARM_standard::foo-6763ac6ae31fbc1a89ed98c53d443ce8</job>
<arch>armv7l</arch>
<hostarch>x86_64</hostarch> <additional_archs arch="x86_64" sysroot="/" /> <!--- actually not required, IIRC ---> <additional_archs arch="armv7l" sysroot="/sysroot/armv7l" /> <additional_archs arch="armv5el" sysroot="/sysroot/armv5el" /> [...] <bdep name="aaa_base" preinstall="1" runscripts="1" notmeta="1" neededbyhost="1" /> [...] <bdep name="tar" preinstall="1" neededbyhost="1" /> [...] <bdep name="libsepol1" vminstall="1" target_arch="x86_64" /> <bdep name="libblkid1" vminstall="1" notmeta="1" target_arch="x86_64" /> <bdep name="libuuid1" vminstall="1" notmeta="1" target_arch="x86_64" /> <bdep name="gcc" /> <bdep name="gcc46" /> <bdep name="patch" /> <bdep name="cpp" /> [...] <bdep name="tar" /> [...] <path project="home:Admin" repository="openSUSE_Factory_ARM_standard" server="http://srsyy.b1-systems.de:5252" /> <path project="openSUSE:Factory:ARM" repository="standard" server="http://srsyy.b1-systems.de:5252" /> </buildinfo> --->8---
The parameter "target_arch" was a first try to define which packages has to be installed in which sysroot, but was a lot to configure in the scheduler and the job info. So at the moment this parameter is removed again and just "neededbyhost" is used to determine packages for hte hostsystem. Now all packages withouth "neededbyhost" attribute are installed in all sysroots for additional architectures. Don't know if this is the best way, but at the moment the easiest to test the crossbuilding. What do you think would be a good way for this? Should the bdep-packages become tagged with the architecture they are needed in? Regards, Christian - - -- Christian Schneemann Linux Consultant & Developer Mail: schneemann@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg / http://www.b1-systems.de GF: Ralph Dehner / Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537 - -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.18 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk9GiEEACgkQL6hkOkG9q4F6nQCfV1+8M/wu5FAMjHJghMNRyyvq PlgAoIEmuEMwvcHwUI758l+s9RITetlH =HytZ - -----END PGP SIGNATURE----- -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.18 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk9GiKwACgkQL6hkOkG9q4GR6gCgujRZm7KVZFdF0Am0M0LdW1EY CPAAnRiIHPg5qLQXHWY+EIXxhK2MUvEy =s4li -----END PGP SIGNATURE----- -- To unsubscribe, e-mail: opensuse-buildservice+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-buildservice+owner@opensuse.org
(again with the lack of 'reply' to all, ignore previous email please) 23. feb. 2012 19.41 skrev Christian Schneemann <schneemann@b1-systems.de>:
The parameter "target_arch" was a first try to define which packages has to be installed in which sysroot, but was a lot to configure in the scheduler and the job info. So at the moment this parameter is removed again and just "neededbyhost" is used to determine packages for hte hostsystem.
Now all packages withouth "neededbyhost" attribute are installed in all sysroots for additional architectures. Don't know if this is the best way, but at the moment the easiest to test the crossbuilding.
What do you think would be a good way for this? Should the bdep-packages become tagged with the architecture they are needed in? If you're really planning on N sysroots, it'd be good to tag them specifically with what sysroot to put them into, even the / one, IMHO.
Keep in mind that you might have to maintain this behaviour for a longer time as patches will go into 'build' and 'osc' and hence be difficult to revert on developer machines / remain compatible with older OBS instances, so it's best to do it right the first time. For initial development/proof of concept it makes sense to restrict to 2 roots (host and target) BR Carsten Munk -- To unsubscribe, e-mail: opensuse-buildservice+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-buildservice+owner@opensuse.org
23. feb. 2012 19.21 skrev Daniel Gollub <gollub@b1-systems.de>:
Hi Carsten, Hi Adrian, On Thursday, February 16, 2012 11:01:15 AM Adrian Schröter wrote:
Am Donnerstag, 16. Februar 2012, 10:43:01 schrieb Carsten Munk: [...]
Daniel Gollub suggested that we work with N amount of 'sysroots' and N rpm databases and I tend to agree. Right now in SB2 I distinguish between host (/) and target /target, but it might be more flexible to do with N targets instead. Scheduler and Worker modification by Christian:
* Add new parameter to prjconf for additional architectures
New parameter 'AdditionalArch' added to projectconfiguration (prjconf). This parameter identifies additional architectures with its sysroot that should be downloaded during build preparation.
AdditionalArch: <arch> <sysroot>
I've started to look a bit into your code and I have some questions regarding the intended semantics (because it's probably better to specify these in order to drive proper implementation). Please correct me if I have my understanding wrong. AdditionalArch: <scheduler> <sysroot> (now called Sysroot in the code it seems) which in effect will put install packages from <scheduler> into <sysroot> - I like this approach, quite clean way to do it. Preinstall: and VMinstall: will always go into hostarch (which makes sense) in order to have a bootable environment What scope will BuildRequires: dependencies from the package be resolved with? Will it look within the <scheduler> that it is being built within? Will BuildRequires: be dep resolved on all architectures or just one? Have you considered how to deal with x86_64 cross compiling to x86_64 target as well? (or i586->i586) - that would be a typical use case for 'daily development' kind of things, demo embedded system in a X86 VM for example. That's why I was thinking of labels instead for scheduler. Won't you be having an inconsistent RPM database in the target, as in, 'gcc' package name is not represented in package names when doing substitutions? BR Carsten Munk -- To unsubscribe, e-mail: opensuse-buildservice+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-buildservice+owner@opensuse.org
Hi Carsten, On 02/27/2012 12:33 PM, Carsten Munk wrote:
23. feb. 2012 19.21 skrev Daniel Gollub <gollub@b1-systems.de>:
Hi Carsten, Hi Adrian, On Thursday, February 16, 2012 11:01:15 AM Adrian Schröter wrote:
Am Donnerstag, 16. Februar 2012, 10:43:01 schrieb Carsten Munk: [...]
Daniel Gollub suggested that we work with N amount of 'sysroots' and N rpm databases and I tend to agree. Right now in SB2 I distinguish between host (/) and target /target, but it might be more flexible to do with N targets instead. Scheduler and Worker modification by Christian:
* Add new parameter to prjconf for additional architectures
New parameter 'AdditionalArch' added to projectconfiguration (prjconf). This parameter identifies additional architectures with its sysroot that should be downloaded during build preparation.
AdditionalArch: <arch> <sysroot>
I've started to look a bit into your code and I have some questions regarding the intended semantics (because it's probably better to specify these in order to drive proper implementation). Please correct me if I have my understanding wrong.
AdditionalArch: <scheduler> <sysroot> (now called Sysroot in the code it seems) which in effect will put install packages from <scheduler> into <sysroot> - I like this approach, quite clean way to do it.
First try with AdditionalArch we used just the architecture as label, it was not bind to the scheduler, it just had the same name. You have alreade seen the new Sysroot code, here the parameters are a bit different: Sysroot: <alias> <project> <repo> <arch> <sysroot> You have to define an alias or label, then the project and repo with architecture from where the packages should come from, and last the sysroot where all the things should be installed in. The packages will have an additional Tag 'sysroot' in the jobfile with the alias/label of the sysroot have to be installed.
Preinstall: and VMinstall: will always go into hostarch (which makes sense) in order to have a bootable environment
What scope will BuildRequires: dependencies from the package be resolved with? Will it look within the <scheduler> that it is being built within?
Will BuildRequires: be dep resolved on all architectures or just one?
Have you considered how to deal with x86_64 cross compiling to x86_64 target as well? (or i586->i586) - that would be a typical use case for 'daily development' kind of things, demo embedded system in a X86 VM for example. That's why I was thinking of labels instead for scheduler.
Not considered yet, but that should be possible. We are using now labels too :)
Won't you be having an inconsistent RPM database in the target, as in, 'gcc' package name is not represented in package names when doing substitutions?
Regards, Christian -- Christian Schneemann Linux Consultant & Developer Mail: schneemann@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg / http://www.b1-systems.de GF: Ralph Dehner / Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537 -- To unsubscribe, e-mail: opensuse-buildservice+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-buildservice+owner@opensuse.org
Hi Carsten, On Monday, February 27, 2012 02:17:34 PM Christian Schneemann wrote: [...]
Preinstall: and VMinstall: will always go into hostarch (which makes sense) in order to have a bootable environment
Right.
What scope will BuildRequires: dependencies from the package be resolved with? Will it look within the <scheduler> that it is being built within?
Will BuildRequires: be dep resolved on all architectures or just one?
I just pushed out something which starts addressing this issues: https://github.com/b1-systems/obs-build/commit/930554fe36992097c2b200e6db74a... https://github.com/b1-systems/open-build-service/commit/91bece36f12a8095d6cf... Since we want to have _Transpartent_ cross builds (which means not too much fidlling in each spec file with regards to BuildRequires and other things) I enabled Build::get_build and Build::get_deps to: 1. Substitue cross build dependency e.g. toolchain. Like this (in your prjconf): Substitute: gcc cross-gcc-armv7l(HOST) (no modification on Build.pm required for this) The idea is to assign dependencies to a specific dependency-tree/sysroot by adding a suffix "package(SYSROOT_LABEL)". In the above example and this first the build dependency would end up in: cross-gcc-armv7l(HOST) 2. Additional code directly after the Build::do_subst function get called: - Build::extract_crossdeps extracts cross dependencies, which are marked like this "package(SYSROOT_LABEL)". This function will then return a hash with the SYSROOT_LABEL as key and an array/list of package name which are dependencies for this SYSROOT_LABEL. So this is suitable for N-sysroots. This hash get stored as seperated seperated cross dependency variable and returnted later. 3. In the next step Build::drop_crossdeps will drop cross dependecies from the original dependecy list. Since the expander function would fail to resolve the dependency of: "coss-gcc-armv7l(HOST)" So all those "package(SYSROOT_LABEL)" get dropped from the original list. 4. unmodified Build::expand or BSSolv.xs exapnder get called. The dependency list will only cover native dependencies - so it should expand as always. This requires that the (cross) Substitute from did not break anything. In some cases you might do something like this to no break the expander: Substitute: libmy-devel libmy-devel libmy-devel(HOST) 5. Build::get_deps / Build::get_build returns the expanded dependency list for the target sysroot. The other additional dependencies for the host or other sysroot got not expanded or resolved by Build::get_deps / Build::get_build. I have not tried to resolve them on purpose inside Build:: since it would not use the expander pool from BSSolv of different scheduler instances. The return value slightly changed of Build::get_deps / Build::get_build function: - return ($eok, @deps) + return ($eok, \@deps, \%crossdeps) (if anyone has an idea how to avoid this - please let us know) 6. All the bs_sched (one per architecture) instances call Build::get_deps / Build::get_build once a build need or so get kicked off. Now the scheduler retrives multiple dependency lists: - one resolved for the native architecture for the sysroot target -> @bdeps (like it was before) - one or more unresolved for other sysroots (incl. the host sysroot) -> %crossdeps TODO: find a way how to handle the dependencies for other sysroots Some rough ideas: - dependencies of sysroots with the same architecture could be resolved in the same scheduler instance and block the build or let it fail due unresolved package - dependencies of sysroots with other architecture: * probe/call the other scheduler instances and ask to resolve the dependency? * check if we can get this information from the meta data on the disk? Not yet solved: blocking builds if a dependency from a other architectures is not ready/available. 7. set_building (from bs_sched) get called with an additional parameter: %crossdeps (Since %crossbuild is not yet expanded/resolved correctly - your cross dependecies might not prevent the scheduler to kick off a build which will fail to due missing cross dependencies) Christian is working right now on checking if there %crossdeps is filled with additional dependencies and add those as dependecy into the buildjob file: <bdep name="cross-gcc-armv7l" sysroot="HOST" /> 8. bs_worker retrieves the job and assembles for each sysroot a differnet package list and stores the package also in seperated directories. 9. build script will get called with additional parameters to setup different sysroots. IIRC something like this: build [..] --rpmlist /path/to/worker/package/host/packagelist --sysroot /path/to/sysroot:/path/to/worker/target/pkglist \ --sysroot /path/sysroot2:/path/to/worker/target2/pkglist \ --sysroot /path/sysrootN:/path/to/worker/targetN/pkglist \ --target-sysroot /path/to/sysroot \ --target armv7l 10. init_buildsystem (WIP) setups for each sysroot a seperated package database. Installs package into each sysroot. 11. build kicksoff rpmbuild [...] --target armv7l --root $TARGET_SYSROOT (WIP) ...
Have you considered how to deal with x86_64 cross compiling to x86_64 target as well? (or i586->i586) - that would be a typical use case for 'daily development' kind of things, demo embedded system in a X86 VM for example. That's why I was thinking of labels instead for scheduler.
Not considered yet, but that should be possible. We are using now labels too :)
Right. Since we moved now from AdditoinalArch: to Sysroot: it should be possible to have whatever archiecture you want as additional sysroot. I guess you could even map the Host-Sysroot to something else then /, but then you still need to make sure that your BUILD_ROOT is still works with the buildscript somehow.
Won't you be having an inconsistent RPM database in the target, as in, 'gcc' package name is not represented in package names when doing substitutions?
If we subsitute, lets say "gcc", so it results in cross-gcc-armv7l or something like that - then there would be no BuildRequires/Dependency anylonger for the target once the the job file get assemabled by the scheduler. But as already said, you could also try do some substitution tricks like: Substitute: gcc cross-gcc-armv7l(HOSTLABEL) gcc Which would add cross-gcc-armv7l as dependency for the sysroot with the label HOSTLABLEL and it would be still a regular buildrequires for the target. This way could populated the other sysroots as well by doing this: Subsitute: libfoo libfoo libfoo(petproject_armv7l) libfoo(petproject_i586) or even do this directly in your spec file: BuildRequires: libfoo(petproject_armv7l) libfoo(petproject_i586) [..] Best Regards, Daniel -- Daniel Gollub Linux Consultant & Developer Tel.: +49-160 47 73 970 Mail: gollub@b1-systems.de B1 Systems GmbH Osterfeldstraße 7 / 85088 Vohburg / http://www.b1-systems.de GF: Ralph Dehner / Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537
27. feb. 2012 18.17 skrev Daniel Gollub <gollub@b1-systems.de>:
Hi Carsten,
On Monday, February 27, 2012 02:17:34 PM Christian Schneemann wrote: [...]
Preinstall: and VMinstall: will always go into hostarch (which makes sense) in order to have a bootable environment
Right.
What scope will BuildRequires: dependencies from the package be resolved with? Will it look within the <scheduler> that it is being built within?
Will BuildRequires: be dep resolved on all architectures or just one?
I just pushed out something which starts addressing this issues: https://github.com/b1-systems/obs-build/commit/930554fe36992097c2b200e6db74a... https://github.com/b1-systems/open-build-service/commit/91bece36f12a8095d6cf...
Since we want to have _Transpartent_ cross builds (which means not too much fidlling in each spec file with regards to BuildRequires and other things) I enabled Build::get_build and Build::get_deps to:
<snip> Sounds like a good direction - I think I'll begin to rebase my SB2 work on top of your patches as to make merging of both our efforts easier. BR Carsten Munk -- To unsubscribe, e-mail: opensuse-buildservice+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-buildservice+owner@opensuse.org
28. feb. 2012 07.50 skrev Carsten Munk <carsten.munk@gmail.com>:
27. feb. 2012 18.17 skrev Daniel Gollub <gollub@b1-systems.de>:
Hi Carsten,
On Monday, February 27, 2012 02:17:34 PM Christian Schneemann wrote: [...]
Preinstall: and VMinstall: will always go into hostarch (which makes sense) in order to have a bootable environment
Right.
What scope will BuildRequires: dependencies from the package be resolved with? Will it look within the <scheduler> that it is being built within?
Will BuildRequires: be dep resolved on all architectures or just one?
I just pushed out something which starts addressing this issues: https://github.com/b1-systems/obs-build/commit/930554fe36992097c2b200e6db74a... https://github.com/b1-systems/open-build-service/commit/91bece36f12a8095d6cf...
Since we want to have _Transpartent_ cross builds (which means not too much fidlling in each spec file with regards to BuildRequires and other things) I enabled Build::get_build and Build::get_deps to:
<snip>
Sounds like a good direction - I think I'll begin to rebase my SB2 work on top of your patches as to make merging of both our efforts easier.
Feeding back on this direction, utilizing the good work by B1-systems of the current cross build patches, I've successfully made a proof of concept utilizing it and SB2, though the code should be less hacky, it seems like a sound direction so far, so we can have the two different cross concepts running side by side. This log from 'build' is the output of sudo /usr/bin/build --root=/home/carsten/NOBACKUP/obs/build-Core_armv7l-i586 --rpmlist=$PWD/rpm-x86.rpmlist --sysroot=/opt/cross/armv7l:$PWD/rpm-arm.rpmlist --dist=/home/carsten/cross/testsuite/_buildconfig-Core_armv7l-i586 --arch=armv7el --target=armv7l-meego-linux --norootforbuild --changelog --jobs=2 --uid=500:500 /home/carsten/cross/home:Admin:busybox/busybox/busybox.spec :: http://releases.merproject.org/~carsten/cross-build-sb2.txt This succesfully sets up a X86 host + ARM target chroot with capability to run postscripts, ARM binaries, etc and does the build within SB2 with fast x86 tools. Without the use of binfmt_misc, or modifications of RPM configurations, etc. BR Carsten Munk -- To unsubscribe, e-mail: opensuse-buildservice+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-buildservice+owner@opensuse.org
participants (4)
-
Adrian Schröter
-
Carsten Munk
-
Christian Schneemann
-
Daniel Gollub