Opened 4 years ago

Closed 15 months ago

#4163 closed task (fixed)

Make cross-compilation work

Reported by: simonmar Owned by:
Priority: high Milestone: 7.8.1
Component: Build System Version: 6.12.3
Keywords: Cc: michael@…, middleton.ted@…, brian.bloniarz@…, pho@…, shelarcy@…, leoncamel@…, william.knop.nospam@…, karel.gardas@…, dankna@…, leather@…, pumpkingod@…, dterei
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty: Difficult (2-5 days)
Test Case: Blocked By:
Blocking: Related Tickets:

Description

Attachments (2)

cross1.dpatch (133.4 KB) - added by igloo 4 years ago.
dnk-cross-compilation.dpatch.gz (234.2 KB) - added by dankna 3 years ago.

Download all attachments as: .zip

Change History (32)

Changed 4 years ago by igloo

comment:1 Changed 4 years ago by igloo

  • Milestone changed from 6.14.1 to 6.14.2

I've attached a patch which gets me to the point that I can cross-compile to OSX 64.

It needs some polishing. We also want to make the RTS use HOST, rather than TARGET, variables if possible.

This is probably the easiest cross-compilation scenario, as the same machine can run both OSX 32 and OSX 64 programs, so there are doubtless more things that would need fixing for other scenarios.

I don't think we'll make more progress on this before 6.14.1, though.

comment:2 Changed 4 years ago by mndrix

  • Cc michael@… added

comment:3 Changed 4 years ago by tedm

  • Cc middleton.ted@… added

comment:4 Changed 3 years ago by phunge0

  • Cc brian.bloniarz@… added

comment:5 Changed 3 years ago by PHO

  • Cc pho@… added

comment:6 Changed 3 years ago by shelarcy

  • Cc shelarcy@… added

comment:7 Changed 3 years ago by leoncamel

  • Cc leoncamel@… added

comment:8 in reply to: ↑ description Changed 3 years ago by altaic

  • Cc william.knop.nospam@… added

I just tried compiling HEAD with host = build = target = x86_64-apple-darwin on my OSX (10.6.5) machine (64-bit processor; kernel is booted as 64-bit as well), and it fails with:

"/usr/bin/gcc" -o utils/unlit/dist/build/tmp/unlit  -m64 -fno-stack-protector              utils/unlit/dist/build/unlit.o    
ld: warning: in utils/unlit/dist/build/unlit.o, file was built for i386 which is not the architecture being linked (x86_64)
Undefined symbols:
  "_main", referenced from:
      start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make[1]: *** [utils/unlit/dist/build/tmp/unlit] Error 1
make: *** [all] Error 2

I'll hazard a guess that this is because the configure scripts for libraries/integer_gmp and libraries/unix are autodetecting host, build, and target as i386. Shouldn't libraries inherit host, build, and target from the "overall" configure script a la CrossCompilation?

For reference, a standard i386 build (no configure options) does pretty well, until it inexplicably fails in stage 2 with "make[1]: * [libraries/vector/dist-install/build/Data/Vector/Fusion/Stream/Monadic.o] Bus error", but that's for another ticket. :)

comment:9 Changed 3 years ago by altaic

Oops! I somehow mixed things up when I mentioned libraries/integer_gmp and libraries/unix (I had a different failure with them, which was due to them being automatically configured for i386 even though I'd specified x86_64 to the overall configure script).

I typed up a huge response detailing two bugs (plus workarounds and resolutions) with the build system that caused build failure at unlit, but I've instead decided to split them into separate tickets. Since they block this ticket, I'll post a comment here after filing them (and others I find) tonight.

comment:10 Changed 3 years ago by altaic

Tickets (and patches) as promised:

  • #4818 (isysroot mixup)
  • #4819 (architecture mixup)

I am investigating a couple other issues, but I'm not sure if they're just something screwy with a previous ghc install or a real bug.

comment:11 Changed 3 years ago by altaic

Sorry for the bad links... These are the tickets:

  • 4818 (isysroot mixup)
  • 4819 (architecture mixup)

comment:12 Changed 3 years ago by kgardas

  • Cc karel.gardas@… added

comment:13 Changed 3 years ago by simonmar

  • Milestone changed from 7.0.2 to 7.2.1

comment:14 Changed 3 years ago by dankna

  • Cc dankna@… added

comment:15 Changed 3 years ago by spl

  • Cc leather@… added

comment:16 Changed 3 years ago by dankna

Okay - I am about to attach a patch. I'd like this patch merged as soon as possible, even though it only solves part of the problem, because of its large size (wc says the diff is 6700 lines, so I assume it touches about half that many). I'm terrified to death of having to redo the work because of conflicts! :)

This patch does several things towards my first goal of removing all preprocessor use from the compiler/ subtree.

First, it adds a new file basicTypes/Architecture.hs which contains a taxonomy of platforms we support. This is distinct from the old nativeGen/Platforms.hs (which this patch removes, changing all uses of it to support the new system) in that it includes second- and even third-tier platforms, not just those for which we have native generators available. Currently there are three fields to it - Processor, Vendor, and Kernel. Eventually there will be an additional field ABI (application binary interface), holding all the information that's currently determined by GNU autoconf, so that it's available at runtime. There is a new field targetArchitecture :: Architecture in the dynamic flags, currently initialized by the preprocessor; this should be easy to change to initializing from the command-line when we get that far.

Second, it threads parameters of this Architecture type everywhere they're needed. This mostly means to the preprocessor, or to functions which call the preprocessor - which means practically everything, unfortunately. Where it made sense to add it to a monad instead of making it an explicit parameter, I did that, but it very seldom did. I did talk to dcoutts about possible other strategies, and he agreed that this one made sense (the channel logs of #ghc should have our full discussion, probably sometime last week); there are several motivating forces, but most notably, I can't make the type of Instruction determine how things are pretty-printed, because some architectures share Instruction types but not pretty-printing styles. I should note here that the pretty-printer is used to interface with external tools, such as gcc and llvm, and is thus a "mission-critical" component, not merely for debugging use!

Third, it takes out quite a lot of Outputable instances, replacing them with functions in the style pprThing :: Architecture -> SDoc. Also there's a couple in the style pprList :: (a -> SDoc) -> [a] -> SDoc. The instances are no longer viable because the preprocessor had been used to select which instance to use, and we need to make that determination at runtime to support multiple targets from a single binary of ghc.

Generally the "damage" this caused was fairly limited, but a single Outputable instance, that on CLabel, by its removal forced Architecture to be threaded in both llvmGen/ and codeGen/ - I verified very carefully that this was a genuine portability issue and not something I could stub around by forking the implementation or something. The issue was that underscore prefixing and other name-mangling had been controlled by the preprocessor, and again, now we need to make the decision at runtime. The good news is that I completed that part of the work!

Third, it reconciles and takes out some old notions that were grasping for the same thing as the Architecture taxonomy but in less complete ways. Specifically, this is done for nativeGen/Platform.hs (as noted above), and for the elf_OBJ_FORMAT macro. I would like to note by way of bragging that having threaded the Architecture made it very easy to take out the elf_OBJ_FORMAT macro.

Fourth, it includes Igloo's patch above, and resolves conflicts that had arisen in it. The full import of this patch is not clear to me, but mostly it seems to be changing things to use *_TARGET_ARCH instead of *_HOST_ARCH. To this extent, it may be irrelevant, since the ultimate goal is to remove these altogether - and I believe that that's no more than another two weeks of work away, at the worst, and probably less.

Future work will take out the IF_ARCH_* macros and the *_TARGET_ARCH macros. I had originally planned to submit this for merging once that was complete, but the patch in its current form does pass validate for me, or, at least, causes no "unexpected failures" that I wasn't getting from HEAD without my patch. But given the multi-architecture nature of this patch, people should check that on other platforms as well!

Changed 3 years ago by dankna

comment:17 Changed 3 years ago by dankna

  • Status changed from new to patch

comment:18 Changed 3 years ago by pumpkin

  • Cc pumpkingod@… added

comment:19 Changed 3 years ago by simonpj

  • Owner set to simonmar

Dear dankna, thank you for doing this work. Simon M is on holiday and he'll definitely need to review it, which he can do when he gets back.

Big patches are something of a high-risk strategy! It's usually better to propose and discuss a design before investing your cycles in executing on it. But regardless, thank you for rolling up your sleeves. We need people who will do that.

Simon

PS: assigning to Simon M because we can't proceed without your say-so!

comment:20 Changed 3 years ago by dankna

Thanks! I absolutely agree that it's high-risk. I had in fact talked over my plans somewhat on IRC, mostly with Duncan and also a bit with Ian, so I felt relatively safe in doing the work. Unfortunately it turned out that I couldn't just thread the parameters one place without threading them /everywhere/, and I got a little carried away in doing that, yes. Hopefully it'll work out for this patch. The rest of the work should be much, much more subdivisible and doable in smaller patches.

comment:21 Changed 3 years ago by simonmar

Thanks for the patch - I have a large backlog at the moment so I won't be able to get to this for a few days at least.

comment:22 Changed 3 years ago by simonmar

A few quick comments:

Igloo's patch isn't right - it changes *_HOST_ARCH to *_TARGET_ARCH in the RTS, and we eventually agreed that is the wrong thing (IIRC).

We have some conflict resolutions in there (merger patches), would be good to get rid of those. Basically I think Igloo's patches need to be rebased on HEAD.

You have some whitespace changes in there, which makes it hard to review the patch, could you separate them out please?

In general, I have concerns that passing DynFlags? everywhere will be too painful, and I wonder whether we should put the target architecture in a static flag instead (i.e. something in main/StaticFlags.hs). The downsides are minimal - you wouldn't be able to fire up two GHC sessions using the GHC API and generate code for two different platforms, but I don't expect anyone would want to do that.

comment:23 Changed 3 years ago by simonmar

Dan, what are your plans with this? Are you revising the patch?

comment:24 Changed 3 years ago by dankna

Yes, sorry for the lack of updates. I'm still working on it (and coordinating with copumpkin, who offered to assist), revising it per our discussion a couple weeks ago.

comment:25 Changed 3 years ago by dterei

  • Cc dterei added

comment:26 Changed 3 years ago by simonmar

  • Owner simonmar deleted

unassigning myself, I don't think I own this ticket

comment:27 Changed 3 years ago by igloo

  • Milestone changed from 7.4.1 to 7.6.1

Punting

comment:28 Changed 2 years ago by igloo

  • Status changed from patch to new

comment:29 Changed 21 months ago by igloo

  • Milestone changed from 7.6.1 to 7.8.1

Punting

comment:30 Changed 15 months ago by simonmar

  • Resolution set to fixed
  • Status changed from new to closed

Closing - it is mostly working now (see Building/CrossCompiling for instructions). The remaining issues have separate tickets.

Note: See TracTickets for help on using tickets.