Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 774540 - dev-lang/ghc: cross compilation of haskell packages fails
Summary: dev-lang/ghc: cross compilation of haskell packages fails
Status: CONFIRMED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Current packages (show other bugs)
Hardware: All Linux
: Normal normal
Assignee: Cross compilation support
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-03-06 22:36 UTC by Enrique Domínguez
Modified: 2023-02-09 01:20 UTC (History)
3 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Enrique Domínguez 2021-03-06 22:36:05 UTC
I want to cross build ghc from x86_64 (CBUILD) to i586 (CHOST) bootstraped. Started compiling ghc for CBUILD and then boostrapped for CHOST. Some guidance from:
https://gentoohaskell.wordpress.com/2017/04/15/ghc-as-a-cross-compiler-update/

Cross compiling ghc gave me several problems:

1) when compiling lib for i586 which depends on another libs, build fails always. In i586 database (/usr/CHOST/usr/{libdir}/ghc-<ver>/package.conf.d/*.conf) files ended .conf had incorrect path (they point to '/usr/lib64/CHOST-ghc-<ver>' inestad of '/usr/CHOST/usr/{libdir}/ghc-<ver>'). This could be solved making symlinks /usr/{libdir}/<ghclib> -> /usr/CHOST/usr/{libdir}/<ghclib> for each lib.

2) If you update an internal lib of ghc in CBUILD making link:
{cross overlay} -> {haskell overlay}
/usr/local/portage/cross-CHOST/cabal -> /usr/portage/dev-haskell/cabal
then libs get installed on /usr/{libdir}/<ghclib>
but if you installs dev-haskell/cabal for CBUILD too, get installed same folder (package collision)

3) db on /usr/CHOST/usr/{libdir}/ghc-<ver>/package.conf.d/ never (auto) recache on new installs

For 1) and 2) maybe could be possible install always ghc as cross ghc on:
/usr/{libdir}/CBUILD-ghc-<ver> for CBUILD and 
/usr/{libdir}/CBUILD-ghc-<ver> for CHOST
and libraries
/usr/lib64/CBUILD-ghc-<ver>/libs/lib-<ver> for CBUILD
where 'CBUILD-ghc-<ver>/libs/lib-<ver>' is libsubdir reversed and ../libs/..
 added for splitting from other files

then we only need link in CBUILD:
/usr/{libdir}/CHOST-ghc-<ver> -> /usr/CHOST/usr/lib64/CHOST-ghc-<ver>
and could complile libs in CHOST.

For 3) maybe
/usr/{libdir}/CBUILD-ghc-<ver>/crosslibs/lib-<ver>? then needing to fix env var GHC_PACKAGE_PATH ?

Many things over long time to get it working, hope it helps.
Comment 1 Sergei Trofimovich (RETIRED) gentoo-dev 2021-03-08 07:48:47 UTC
(In reply to Enrique Domínguez from comment #0)
> I want to cross build ghc from x86_64 (CBUILD) to i586 (CHOST) bootstraped.
> Started compiling ghc for CBUILD and then boostrapped for CHOST. Some
> guidance from:
> https://gentoohaskell.wordpress.com/2017/04/15/ghc-as-a-cross-compiler-
> update/
> 
> Cross compiling ghc gave me several problems:

To clarify: What package did you actually build: dev-lang/ghc, cross-i586-unknown-linux-gnu/ghc? or something else?

Was there any problem building the package itself? It's not clear from below. If it was please attach build.log and emerge.info.

Also please state explicitly your end goal: just cross-building ghc or also cross-build haskell packages?

> 1) when compiling lib for i586 which depends on another libs, build fails
> always. In i586 database
> (/usr/CHOST/usr/{libdir}/ghc-<ver>/package.conf.d/*.conf) files ended .conf
> had incorrect path (they point to '/usr/lib64/CHOST-ghc-<ver>' inestad of
> '/usr/CHOST/usr/{libdir}/ghc-<ver>'). This could be solved making symlinks
> /usr/{libdir}/<ghclib> -> /usr/CHOST/usr/{libdir}/<ghclib> for each lib.

No. /usr/CHOST is a root of target system. It should be chroot-able and usable as is. There should be no references to /usr/CHOST/usr/.

> 2) If you update an internal lib of ghc in CBUILD making link:
> {cross overlay} -> {haskell overlay}
> /usr/local/portage/cross-CHOST/cabal -> /usr/portage/dev-haskell/cabal
> then libs get installed on /usr/{libdir}/<ghclib>
> but if you installs dev-haskell/cabal for CBUILD too, get installed same
> folder (package collision)

I don't think we ever finished work to cross-build haskell libraries. haskell-cabal.eclass probably needs more work.

> 3) db on /usr/CHOST/usr/{libdir}/ghc-<ver>/package.conf.d/ never (auto)
> recache on new installs

Same as above. haskell-cabal.eclass probably needs more work to call correct ghc-pkg against correct `ghc --print-global-package-db`.
Comment 2 Enrique Domínguez 2021-03-09 20:59:28 UTC
(In reply to Sergei Trofimovich from comment #1)
> To clarify: What package did you actually build: dev-lang/ghc,
> cross-i586-unknown-linux-gnu/ghc? or something else?
I built dev-lang/ghc for my x86_64 (CBUILD) and then cross-i586-unknown-linux-gnu/ghc[bootstrap] for i586 (CHOST). All went without errors. Problem appears when CHOST-emerge interdepend ghc libraries. Actual error was missing files. If ghc lib depends only on bundled ghc ones all works. But fails if depends include some CHOST installed one.
 
> Was there any problem building the package itself? It's not clear from
> below. If it was please attach build.log and emerge.info.
No problems at this point.
 
> Also please state explicitly your end goal: just cross-building ghc or also
> cross-build haskell packages?
Cross haskell packages. I built games-strategy/hedgewars[server] ebuild customized for building only hedgewars-server. (Done)

> > 1) when compiling lib for i586 which depends on another libs, build fails
> > always. In i586 database
> > (/usr/CHOST/usr/{libdir}/ghc-<ver>/package.conf.d/*.conf) files ended .conf
> > had incorrect path (they point to '/usr/lib64/CHOST-ghc-<ver>' inestad of
> > '/usr/CHOST/usr/{libdir}/ghc-<ver>'). This could be solved making symlinks
> > /usr/{libdir}/<ghclib> -> /usr/CHOST/usr/{libdir}/<ghclib> for each lib.
> 
> No. /usr/CHOST is a root of target system. It should be chroot-able and
> usable as is. There should be no references to /usr/CHOST/usr/.
Let me explain a little more. Agree with you "usable as is", but cross-ghc can't find installed libs because when look for files in CHOST db (as far i know) it reads paths as '/usr/{libdir}/<ghcLibPkg>' (as .conf says) which don't exists. But if I make links: /usr/{libdir}/<ghcLibPkg> -> /usr/CHOST/usr/{libdir}/<ghcLibPkg>  then all works. From there follows my proposal, fix libsubdir as 'CBUILD-ghc-<ver>/libs/lib-<ver>' and make only one link in CBUILD,
/usr/{libdir}/CHOST-ghc-<ver>/libs -> /usr/CHOST/usr/{libdir}/CHOST-ghc-<ver>/libs
This requiring all ghclibs updated or only haskell-cabal.eclass?

>> then we only need link in CBUILD:
>> /usr/{libdir}/CHOST-ghc-<ver> -> /usr/CHOST/usr/lib64/CHOST-ghc-<ver>
>> and could complile libs in CHOST.
I think this link won't work. I was wrong.
I'm new to ghc and prefer share my throughts. Couldn't find any help anywhere about cross building ghc interdepend libs.

> Same as above. haskell-cabal.eclass probably needs more work to call correct
> ghc-pkg against correct `ghc --print-global-package-db`.
Cross building hedgewars-server was easy exporting good GHC_PACKAGE_PATH, I didn't find in wrapper script to cross-ghc. Works with ghc-pkg too.

Thanks for your replies.
Comment 3 Sergei Trofimovich (RETIRED) gentoo-dev 2021-03-09 21:43:35 UTC
Aha, let's tweak the title a little.

Yeah, I agree cross-building packages is tricky.

If we followed gcc model perfectly we could do something like the following:
1. require user to install cross-${CHOST}/ghc
2. require user to install dev-lang/ghc to ROOT=/usr/${CHOST}
3. teach cross-${CHOST}/gcc to have equivalent of --sysroot=/usr/${CHOST}
4. Probably tweak eclasses a bit.

In practice [2.] is almost never needed for gcc and copying a library or two from cross-${CHOST}/gcc is enough. We could try to do the same for ghc. Then the layout would be:

1. require user to install cross-${CHOST}/gcc
2. teach cross-${CHOST}/ghc to have equivalent of --sysroot=/usr/${CHOST} (with a fallback to packages in cross-${CHOST}/ghc's package database)
3. Probably tweak eclasses a bit more

I'd like to avoid symlinks between build system and ROOT if we could handle it. But as a workaround before something that works exists they should are great proof of concept.

I'll toy a bit with cross-building smaller packages and libraries to see how we can rewrite package database between CBUILD and CHOST  if possible.
Comment 4 Enrique Domínguez 2021-03-10 01:30:34 UTC
(In reply to Sergei Trofimovich from comment #3)
> 2. require user to install dev-lang/ghc to ROOT=/usr/${CHOST}
Just for the record, if you try these, ebuild mess CHOST and fails. I don't want to pollute the bugreport mixing things. I'll coment you all the stuff along the way.

> 2. teach cross-${CHOST}/ghc to have equivalent of --sysroot=/usr/${CHOST}
> (with a fallback to packages in cross-${CHOST}/ghc's package database)
I don't play with sysroot ever but like to ear about.

> 3. Probably tweak eclasses a bit more
Please keep an eye in package collision if you install a ghclib on CBUILD and later install the same ghclib for CHOST via cross-CHOST/ghclib (the only way for ghc blundled libs) It's a hard process because creating symlinks in cross dir to each lib bundled with ghc which you want updated. For cross build libs, could be better disable collision detection funcion in ghc-package[check-for-collisions] eclass and let install directly on CBUILD all the stuff?
 
> I'll toy a bit with cross-building smaller packages and libraries to see how
> we can rewrite package database between CBUILD and CHOST  if possible.
If you use envvar like this GHC_PACKAGE_PATH="/usr/CHOST/usr/{libdir}/ghc-<ver>/package.conf.d:"
makes cross db taking precedence over global dabase.

And making (without final ':'), GHC_PACKAGE_PATH="/usr/CHOST/usr/{libdir}/ghc-<ver>/package.conf.d" ghc-pkg recache, for example, must done the right thing.
Or,
GHC_PACKAGE_PATH="/usr/CHOST/usr/{libdir}/ghc-<ver>/package.conf.d" HC=CHOST-ghc  ghc-getghcpkg reache
using ghc-package eclass.

I have no tested that things because no idea howto test eclasses quickly, without the time consuming task of calling emerge.