Skip to content
This repository has been archived by the owner on Aug 2, 2020. It is now read-only.

Support building cross compilers #177

Closed
angerman opened this issue Jan 17, 2016 · 28 comments
Closed

Support building cross compilers #177

angerman opened this issue Jan 17, 2016 · 28 comments

Comments

@angerman
Copy link
Collaborator

We basically need to build the stage1 compiler and then build
all the libs using the stage1 compiler, but we do not need to
build the stage2 compiler, as the stage2 compiler would run
on the target, which we do not intend to do.

@angerman
Copy link
Collaborator Author

@thomie
Copy link

thomie commented Jan 17, 2016

See also these Notes in mk/config.mk.in:

And from the toplevel ghc.mk file:

@angerman
Copy link
Collaborator Author

@thomie thanks so much for adding the links.

  • first of all, ghc-stage1 can't use stage0's ghc library (it's too old)

(from the ghc.mk)

Makes me wonder if one might want to explicitly tell the build that one is using the exactly same version to build the cross compiler. E.g. say you build a full stage2 compiler from source and use that to build the cross compiler. In that case, I don't see why one could not use stage0's ghc library. Of course in the general case, it's too old.

@snowleopard snowleopard added this to the ghc-quake milestone Jan 17, 2016
@ggreif
Copy link
Contributor

ggreif commented Jan 17, 2016

I guess that looking at the GIT commit should be enough to decide it.

Em domingo, 17 de janeiro de 2016, Moritz Angermann <
[email protected]> escreveu:

@thomie https://github.com/thomie thanks so much for adding the links.

  • first of all, ghc-stage1 can't use stage0's ghc library (it's too old)

Makes me wonder if one might want to explicitly tell the build that one is
using the exactly same version to build the cross compiler. E.g. say you
build a full stage2 compiler from source and use that to build the cross
compiler. In that case, I don't see why one could not use stage0's ghc
library. Of course in the general case, it's too old.


Reply to this email directly or view it on GitHub
#177 (comment)
.

@kgardas
Copy link
Collaborator

kgardas commented Jan 17, 2016

For porting GHC it's also very good to have an option to build stage2 compiler while cross-compiling. You will then be theoretically able to move ghc-stage2 to the target platform and use it as a native compiler...

@angerman
Copy link
Collaborator Author

@kgardas for porting certainly. But technically I don't consider a stage2 compiler a cross compiler anymore, as it targets the same platform it runs on.

@izgzhen
Copy link
Collaborator

izgzhen commented Jun 28, 2017

Tried a few times but never succeeded in building GHC target=arm-linux-gnueabi for ghc-8.2 on Ubuntu 16.04.2 LTS, LLVM 4.0.

Stuck:

"inplace/bin/ghc-stage1" -static -O0 -H64m -Wall   -Iincludes -Iincludes/dist -Iincludes/dist-derivedconstants/header -Iincludes/dist-ghcconstants/header -Irts -Irts/dist/build -DCOMPILING_RTS -this-unit-id rts -optc-DNOSMP -dcmm-lint      -i -irts -irts/dist/build -Irts/dist/build -irts/dist/build/./autogen -Irts/dist/build/./autogen           -O2    -Wnoncanonical-monad-instances  -c rts/StgStartup.cmm -o rts/dist/build/StgStartup.o
/tmp/ghc858_0/ghc_8.s: Assembler messages:

/tmp/ghc858_0/ghc_8.s:41:0: error:
     Error: selected processor does not support `ldrd r0,r1,[r3,#64]' in ARM mode
   |
41 |         ldrd    r0, r1, [r3, #64]
   | ^

which is similar to https://ghc.haskell.org/trac/ghc/ticket/11058

Also tried lower versions, but failed for some other confusing reasons.

@bgamari @angerman Is there any suggestion what cross-compile setup for HEAD ghc would be an ideal choice for reference implementation?

@Ericson2314
Copy link

Ericson2314 commented Jun 28, 2017

@izgzhen That looks like with GCC. You need a -marmv7-a or similar to get at all the registers.

@izgzhen
Copy link
Collaborator

izgzhen commented Jun 29, 2017

Added a -optc-march=armv7-a but its doesn't really work.

"inplace/bin/ghc-stage1" -static -optc-march=armv7-a -O0 -H64m -Wall   -Iincludes -Iincludes/dist -Iincludes/dist-derivedconstants/header -Iincludes/dist-ghcconstants/header -Irts -Irts/dist/build -DCOMPILING_RTS -this-unit-id rts -optc-DNOSMP -dcmm-lint      -i -irts -irts/dist/build -Irts/dist/build -irts/dist/build/./autogen -Irts/dist/build/./autogen           -O2    -Wnoncanonical-monad-instances  -c rts/StgStartup.cmm -o rts/dist/build/StgStartup.o

Tried adding -optc-marm as well, not working in the same way.

If I add -optc-march=armv7, the error is different:

rts/StgStartup.cmm:1:0: error:
     error: target CPU does not support ARM mode

@Ericson2314
Copy link

@izgzhen so I was working with Nix, and I just modified the shell script wrapping gcc to include the flag. I think the key difference here is that made sure that the flag always got to the gcc targeting the target platform, and never to the "build cc" gcc targeting the host platform. My guess is your second error is that latter gcc being confused.

@izgzhen
Copy link
Collaborator

izgzhen commented Jun 29, 2017

Hmm...so you wrapped <target>-gcc with additional -m flag?

But this doesn't quite work for me. I think my ghc-stage1 did invoke the right <target>-gcc with -march=armv7 added, but still it said:

error: target CPU does not support ARM mode

@Ericson2314
Copy link

Odd. Perhaps your tool chain actually was built targeting different 32-bit arm variant?

@izgzhen
Copy link
Collaborator

izgzhen commented Jun 29, 2017

Aha, I found it. Grepping give me ("target arch", "ArchARM {armISA = ARMv5, armISAExt = [], armABI = SOFT}"), in settings, so I tried -march=armv5, -march=armv5e, -march=armv5t and -march=armv5te (info from <target>-gcc --help=target. The last one works.

@izgzhen
Copy link
Collaborator

izgzhen commented Jun 29, 2017

I have no idea why my arm-linux-gnueabi-gcc-4.7 choose this though..

@Ericson2314
Copy link

Try putting armv7a (no dash now) in the triple.

@izgzhen
Copy link
Collaborator

izgzhen commented Jun 29, 2017

Still not working: I added several wrapper like below:

cat $(which armv7a-linux-gnueabi-gcc) 
#!/bin/bash
/usr/bin/arm-linux-gnueabi-gcc-4.7 -march=armv7-a $@

and ./configure --target=armv7a-linux-gnueabi --with-ld=arm-linux-gnueabi-gcc-ld --with-ld.gold=arm-linux-gnueabi-ld.gold --with-nm=arm-linux-gnueabi-nm --with-ar=arm-linux-gnueabi-ar --with-ranlib=arm-linux-gnueabi-ranlib. But compiling the RTS again gives me error:

"inplace/bin/ghc-stage1" -optc-std=gnu99 -optc-marm -optc-fno-stack-protector -optc-Wall -optc-Wall -optc-Wextra -optc-Wstrict-prototypes -optc-Wmissing-prototypes -optc-Wmissing-declarations -optc-Winline -optc-Waggregate-return -optc-Wpointer-arith -optc-Wmissing-noreturn -optc-Wnested-externs -optc-Wredundant-decls -optc-Iincludes -optc-Iincludes/dist -optc-Iincludes/dist-derivedconstants/header -optc-Iincludes/dist-ghcconstants/header -optc-Irts -optc-Irts/dist/build -optc-DCOMPILING_RTS -optc-DUSE_LIBFFI_FOR_ADJUSTORS -optc-fno-strict-aliasing -optc-fno-common -optc-Irts/dist/build/./autogen -optc-Werror=unused-but-set-variable -optc-Wno-error=inline -optc-O2 -optc-fomit-frame-pointer -optc-g -optc-DRtsWay=\"rts_v\" -optc-w -static  -O0 -H64m -Wall   -Iincludes -Iincludes/dist -Iincludes/dist-derivedconstants/header -Iincludes/dist-ghcconstants/header -Irts -Irts/dist/build -DCOMPILING_RTS -this-unit-id rts -dcmm-lint      -i -irts -irts/dist/build -Irts/dist/build -irts/dist/build/./autogen -Irts/dist/build/./autogen           -O2    -Wnoncanonical-monad-instances  -c rts/StgCRun.c -o rts/dist/build/StgCRun.o
/tmp/ghc11814_0/ghc_1.s: Assembler messages:

/tmp/ghc11814_0/ghc_1.s:43:0: error:
     Error: selected processor does not support `vstmdb sp!,{d8-d11}' in ARM mode
   |
43 |         vstmdb sp!, {d8-d11}
   | ^

/tmp/ghc11814_0/ghc_1.s:52:0: error:
     Error: selected processor does not support `vldmia sp!,{d8-d11}' in ARM mode
   |
52 |         vldmia sp!, {d8-d11}
   | ^

@izgzhen izgzhen self-assigned this Jun 30, 2017
@izgzhen
Copy link
Collaborator

izgzhen commented Jun 30, 2017

Solved the vldmia ... adding -mfloat-abi=hard can solve this since somehow my settings showed that

("target arch", "ArchARM {armISA = ARMv7, armISAExt = [VFPv3,NEON], armABI = SOFT}")

And according to GCC ARM options:

-mfloat-abi=name
Specifies which floating-point ABI to use. Permissible values are: ‘soft’, ‘softfp’ and ‘hard’.

Specifying ‘soft’ causes GCC to generate output containing library calls for floating-point operations. ‘softfp’ allows the generation of code using hardware floating-point instructions, but still uses the soft-float calling conventions. ‘hard’ allows generation of floating-point instructions and uses FPU-specific calling conventions.

The default depends on the specific target configuration. Note that the hard-float and soft-float ABIs are not link-compatible; you must compile your entire program with the same ABI, and link with a compatible set of libraries.

@izgzhen
Copy link
Collaborator

izgzhen commented Jun 30, 2017

I believe the previously failed *.s is generated -- then since before that ARM_ABI is SOFT, why a non-supported instruction is generated?

@bgamari
Copy link
Collaborator

bgamari commented Jun 30, 2017

I suspect you need to instead pass --target=armv7a-linux-gnueabihf. Note the "hf" at the end; it stands for "hard float".

@bgamari
Copy link
Collaborator

bgamari commented Jul 7, 2017

Being curious, I just tried ./configure --target=arm7-linux-gnueabihf; hadrian on GHC HEAD. It managed to build the ghc library but ultimately failed with,

/-------------------------------------------------------------------------\
| Run Ghc LinkHs Stage0 (stage = Stage0, package = check-api-annotations) |
|      input: _build/stage0/utils/check-api-annotations/Main.o            |
|  => output: inplace/bin/check-api-annotations                           |
\-------------------------------------------------------------------------/
/mnt/work/ghc/ghc/_build/stage0/compiler/libHSghc-8.3.a: error adding symbols: Archive has no index; run ranlib to add one
collect2: error: ld returned 1 exit status
`gcc' failed in phase `Linker'. (Exit code: 1)
shakeArgsWith     0.000s    0%                           
Function shake    0.323s    0%                           
Database read     1.360s    0%                           
With database     0.097s    0%                           
Running rules  1294.374s   99%  =========================
Total          1296.154s  100%                           
Error when running Shake build system:
* inplace/bin/check-api-annotations
user error (Development.Shake.cmd, system command failed
Command: /mnt/work/ghc/roots/8.0.2/bin/ghc -Wall -hisuf hi -osuf o -hcsuf hc -static -hide-all-packages -no-user-package-db '-package-db /mnt/work/ghc/ghc/_build/stage0/bootstrapping.conf' '-package-id base-4.9.1.0' '-package-id containers-0.5.7.1' '-package-id Cabal-2.0.0.0' '-package-id directory-1.3.0.0' '-package-id ghc-8.3' -i -i_build/stage0/utils/check-api-annotations -i_build/stage0/utils/check-api-annotations/build/check-api-annotations/autogen -iutils/check-api-annotations/. -Iincludes -I_build/generated -I_build/stage0/utils/check-api-annotations -I/mnt/work/ghc/ghc/compiler -I/mnt/work/ghc/ghc/compiler/parser -I/mnt/work/ghc/ghc/compiler/utils -I/mnt/work/ghc/roots/8.0.2/lib/ghc-8.0.2/process-1.4.3.0/include -I/mnt/work/ghc/roots/8.0.2/lib/ghc-8.0.2/directory-1.3.0.0/include -I/mnt/work/ghc/roots/8.0.2/lib/ghc-8.0.2/unix-2.7.2.1/include -I/mnt/work/ghc/roots/8.0.2/lib/ghc-8.0.2/time-1.6.0.1/include -I/mnt/work/ghc/roots/8.0.2/lib/ghc-8.0.2/bytestring-0.10.8.1/include -I/mnt/work/ghc/roots/8.0.2/lib/ghc-8.0.2/base-4.9.1.0/include -I/mnt/work/ghc/roots/8.0.2/lib/ghc-8.0.2/integer-gmp-1.0.0.1/include -I/mnt/work/ghc/roots/8.0.2/lib/ghc-8.0.2/include -I_build/generated -optc-I_build/generated -optP-include -optP_build/stage0/utils/check-api-annotations/build/check-api-annotations/autogen/cabal_macros.h -optc-fno-stack-protector -odir _build/stage0/utils/check-api-annotations -hidir _build/stage0/utils/check-api-annotations -stubdir _build/stage0/utils/check-api-annotations -no-auto-link-packages -rtsopts _build/stage0/utils/check-api-annotations/Main.o -o inplace/bin/check-api-annotations -O -H32m -optc-Werror=unused-but-set-variable -optc-Wno-error=inline -Wall -XHaskell2010
Exit code: 1
Stderr:
/mnt/work/ghc/ghc/_build/stage0/compiler/libHSghc-8.3.a: error adding symbols: Archive has no index; run ranlib to add one
collect2: error: ld returned 1 exit status
`gcc' failed in phase `Linker'. (Exit code: 1)

It sounds like ranlib was never run on the libHSghc static archive.

@bgamari
Copy link
Collaborator

bgamari commented Jul 7, 2017

The above wasn't actually caused by a missing ranlib run; we use ar q to construct the archive and therefore generally don't need to run ranlib. Instead, this was caused by the wrong ar being used. See #350.

@Ericson2314
Copy link

This applies to both build systems alike, but I now understand there are <TOOL>_FOR_TARGET semi-standard macros for autoconf, which could help disentangle things?

@izgzhen
Copy link
Collaborator

izgzhen commented Aug 22, 2017

I've been hacking on this from time to time in the past month, but it turns out to be quite difficult to take care of. I'll keep working on this, but it might take longer than I initially anticipated.

The first problem is that after #380, the "size doesn't match" in #349 is not solved by that in fact. I compared and tweaked the command line arguments for a long time, but it never worked so well.

@izgzhen
Copy link
Collaborator

izgzhen commented Aug 28, 2017

#401 has given us a working compiling GHC tested on one emulated ARM platform, but it is still crude and needs a lot of polishing. I'll collect the bits needed to be done in future here:

  • More testings
  • grep TargetArch . -nir --include="*.mk"
  • grep HostArch . -nir --include="*.mk"
  • ghc.mk:971 (filled in Use different INSTALLED_GHC_REAL when cross compiling #409)
  • /rules/build-package-data.mk:98:$1_$2_CONFIGURE_OPTS += --configure-option=--host=$(TargetPlatformFull)
  • ./mk/config.mk:619:# C compiler and linker flags from configure (e.g. -m<blah> to select
  • mk/flavours/quick-cross.mk
  • [-] ./libffi/ghc.mk:103: --enable-shared=$(libffi_EnableShared) (filled libffi configure needs libffi_EnableShared flag #405)
  • "inplace/bin/ghc-stage1" -optc-marm
  • We don't need LD_LIBRARY_PATH etc.
  • [-] ./includes/ghc.mk:88: @echo "*** Cross-compiling: please copy $(includes_H_CONFIG) from the target system" (filled in is PORTING_HOST still useful? #407)
  • libffi/ghc.mk:89
  • -static
  • "inplace/bin/ghc-stage1" -fllvm
  • ./src/Settings/Builders/Hsc2Hs.hs:20: , notM windowsHost ? arg "--cross-safe"

@izgzhen
Copy link
Collaborator

izgzhen commented Sep 1, 2017

The above tidbits are all checked, and the remaining few issues are filed as described above.

I think we can close this issue now.

Cc @snowleopard

@izgzhen
Copy link
Collaborator

izgzhen commented Sep 1, 2017

maybe after #410 is merged

@snowleopard
Copy link
Owner

@izgzhen Sounds good! Do close this after we merge #410.

@izgzhen
Copy link
Collaborator

izgzhen commented Sep 11, 2017

I'll close it since #410 is done.

@izgzhen izgzhen closed this as completed Sep 11, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants