ldc-developers / ldc

The LLVM-based D Compiler.
http://wiki.dlang.org/LDC
Other
1.21k stars 261 forks source link

Add iOS, TVOS, and WatchOS support to LDC #1081

Open smolt opened 9 years ago

smolt commented 9 years ago

I thought we could discuss approaches here on how to add iPhoneOS support to LDC. Much of it is prototyped and glued together in https://github.com/smolt/ldc-iphone-dev. Not everything in the repo is needed to support iPhoneOS. Most up-to-date branch is ios. I imagine a bunch of smaller pulls to incrementally add it in.

I am going to start with a rough overview of the changes and an approach can follow. I may come back and edited this overview as I review things.

Inventory of changes

  1. LDC
    1. add iPhoneOS target
      • new version(iOS), version(TvOS), and version(WatchOS) - [in upstream]
      • expanded some isMacOSX code to include iOS (isOSDarwin())
    2. add iOS ABIs (abi-ios-arm and abi-ios-arm64)
    3. cross compiling
      1. real type (both iOS arm/arm64 use 64-bit real) [see #1317]
      2. clang style -arch flag to select darwin target, include x86-based iOS simulator
    4. Generate embedded bitcode. This is probably needed so App Store will accept submissions.
  2. phobos
    1. update unitttests for iOS
    2. some math changes for 64-bit real type
      • tweaks to ARM and AArch64 inline assembly [done]
      • potential fix for #888
    3. std.parallelism fix for iOS
    4. and a couple other changes that have already gone upstream [done]
  3. druntime
    1. iOS support in core.stdc. Code common to OSX and iOS would use version(Darwin) [in upstream]
    2. Thread,Fiber support (ARM and AArch64 tweaks to existing support)
      • includes workaround for Issue #666 [Fiber done]
    3. SjLj exceptions (only 32-bit ARMs use) [done]
    4. add missing AArch64 support
    5. thread local changes to use support code below
    6. and a couple other changes that are already upstream
  4. thread local support via patched LLVM and support code in https://github.com/smolt/iphoneos-apple-support [no longer needed as of LLVM 3.8.0 and iOS 9]
  5. build support
    1. cmake cross compile, and in particular build universal libs
    2. process for making releases

      Version iOS

      • Currently in fork, version(IPhoneOS) version(iOS) is set when triple ends in "ios". version(OSX) is also set because iOS is a kind of OS X and often the OSX code is the correct code for iOS too.
      • Decision: use version(iOS) when triple OS is "ios" instead of IPhoneOS and don't set version(OSX). This aligns with Swift too. Also set version(Darwin) for both.

        Cross compile to target real type

Currently using something I cooked up last year that works when targeting ARM (-DUSE_OSX_TARGET_REAL), but it shouldn't be used. Other approaches are being worked such as #1317.

Support SjLj Exceptions for ARM 32-bit

personality function ldc-developers/druntime#39 Fiber support: [done]

Non-standard LLVM

Yeah! Stock LLVM can be used as of LLVM 3.8.0 and iOS 8 (arm64), iOS 9 (armv7). For earlier iOS version iPhoneOS targets need a small LLVM change to support thread locals. Even the i386 and x86_64 iPhone Simulator SDK doesn't support thread locals and ld complains if darwin TLS relocations show up in an object file. So LLVM AArch64, ARM, and X86 targets have a dab of code to generate a call to __tls_get_addr() which avoids using TLS relocations.

This may not work for app submissions because Apple seems to want to rebuild from LLVM bitcode. Best option here is to only support newest iOS.

Build/Test/Release support

Approach to make universal libs in cmake feels like a kludge, and not sure how to support testing. Still have not run dmd test-suite with cross-compiler.

smolt commented 4 years ago

All I can say is yeah! Happy others took this on. Is it mostly just @jacob-carlborg?

jacob-carlborg commented 4 years ago

All I can say is yeah! Happy others took this on. Is it mostly just @jacob-carlborg?

It’s mostly been me now but kinke has been very helpful with LDC. But you, Joakim (that did the work on Android), kinke and others laid the groundwork. I’m mostly finishing up the work.

If you’re still interested in contributing I could use some help. There are some of the tests in Phobos that are failing, allocator and math related tests.

smolt commented 4 years ago

If you’re still interested in contributing I could use some help.

Wish I had the time. Also I no longer have an iOS dev environment.

etcimon commented 4 years ago

@smolt Anything I (or someone else) can do to make it easier for you?

jacob-carlborg commented 4 years ago

smolt Anything I (or someone else) can do to make it easier for you?

@etcimon I see now that you directed your question to Dan, but if I may interfere. I could use some help, I'm currently working on the iOS support. The PR to LDC [1] has already been merged, which is fantastic. But I could use some help in getting reviews on the PRs for druntime [2] and Phobos [3]. All the unit tests for druntime are passing on the device. Some of the unit tests for Phobos are failing. Apparently I've introduced are regression in the Phobos unit tests for all platforms except macOS [4]. I could use some help in tracking that down as well.

Of course, if you have the equipment for iOS development I could use some help with that. Like figuring out the failing Phobos unit tests. I can give you instructions how to set it up if you're interested.

[1] https://github.com/ldc-developers/ldc/pull/3288 [2] https://github.com/dlang/druntime/pull/2910 [3] https://github.com/dlang/phobos/pull/7355 [4] https://auto-tester.puremagic.com/pull-history.ghtml?projectid=1&repoid=3&pullid=7355

etcimon commented 4 years ago

@jacob-carlborg We have a mac mini and a few iphones here in my family including the newest iPhone and an apple watch. I'd like to test but I would probably need a few instructions. I installed xcode on the mac mini but I'm not sure how to transfer an application over and so on

edit: Perhaps I can give you anydesk access to the mac mini to set things up?

jacob-carlborg commented 4 years ago

@etcimon sure I can help with that. You need to download LDC and LLVM and build LDC as well. You can download LLVM here [1]. Instructions for building LDC are available here [2]. It will take a while to compile LDC.

Make sure you open Xcode once before starting as well. You might need to approve some licenses and download some additional components. If that's required, Xcode will prompt you with a dialog to do so.

Are you available in the dlang workspace on Slack?

[1] http://releases.llvm.org/download.html#9.0.0 [2] https://wiki.dlang.org/Building_LDC_from_source#Building_LDC_from_source

etcimon commented 4 years ago

Unfortunately I'm not in that workspace right now, any way of inviting me?

jacob-carlborg commented 4 years ago

Done. I sent an invitation to the email address you attached to your git commits.

etcimon commented 4 years ago

Took a look today and the allocator issues are due to AscendingPageAllocator having a pageSize of 16384 on iOS vs the tests being run with an assumed pageSize of 4096

jacob-carlborg commented 4 years ago

Took a look today and the allocator issues are due to AscendingPageAllocator having a pageSize of 16384 on iOS vs the tests being run with an assumed pageSize of 4096

Yes, changing the test to use 16384 did not help for me.

etcimon commented 4 years ago

You need to initialize it with that size, then update the numPages and pageSize to the object's values.

etcimon commented 4 years ago
@system @nogc nothrow unittest
{
    size_t pageSize = 4096;
    size_t numPages = 100;
    void[] buf;
    void[] prevBuf = null;
    AscendingPageAllocator a = AscendingPageAllocator(numPages * pageSize);
    // Refresh values due to platform-specific restrictions
    pageSize = a.pageSize;
    numPages = a.numPages;
etcimon commented 4 years ago

I fixed those tests on my fork, I'll update it soon

etcimon commented 4 years ago

The region.d failure has a version(OSX){} else, cancelling the failing test, so I'll change it to version (OSX) {} else version(iOS) {} else, I guess it would be a good assumption?

etcimon commented 4 years ago

https://github.com/etcimon/phobos/commit/5983f9494b7317cc7c16cef8ba990265e7db2b2b

etcimon commented 4 years ago

The math tests all fail on real NaN(ulong payload) which is pure, so it might be a CodeGen issue too

jacob-carlborg commented 4 years ago

The failing math tests were solved for me by disabling the fast mode of the FPU. See the inline assembly here: https://github.com/smolt/ldc-iphone-dev/blob/master/unittester/unittest.d.

etcimon commented 4 years ago

So you think iOS builds should always have fast mode disabled? Or is that just a hint on the CodeGen issue?

etcimon commented 4 years ago

The comment suggests that only the unit tests expect FPU to be disabled, and it can be enabled in regular apps. So everything should be solved except a suspicious socket error now.

etcimon commented 4 years ago

I just tested my botan-math library and it works fine on iOS

etcimon commented 4 years ago

My libasync library is failing so I'll use that to test sockets.

etcimon commented 4 years ago

All math unittests were fixed by the fpu disable flag : https://github.com/etcimon/phobos/commit/4304a2d76a2379e1633bdffde3210c18d9a806d6

Focusing on socket now

jacob-carlborg commented 4 years ago

@etcimon this test is failing for me for some reason: https://github.com/dlang/phobos/blob/7a656e09d23507d0c404dabaa2c440a45e7c753d/std/experimental/allocator/building_blocks/ascending_page_allocator.d#L1012. The value is 0.

etcimon commented 4 years ago

Yes, I forgot that one in the first commit, you need to look at 2 more recent commits on my fork

https://github.com/etcimon/phobos/commit/1539e67cae65e95098c4cbca706fb704e1253f62

etcimon commented 4 years ago

The libasync unittests are working for LDC + iOS now, I didn't need to make many adjustments except for the cache folder being hard to find. I'm not sure why this std.socket test isn't working but the test says PASS so I'd just keep it that way =)

kinke commented 4 years ago

Nice progress. So the core.thread.fiber release unittests are working? They segfault or hang most of the time in my qemu box (Debian on AArch64, emulating Cortex-A57; debug works).

Just keep in mind that you guys are testing the druntime/Phobos unittests, but there are way more tests in the whole testsuite - our LDC-specific lit tests (tests subdir in LDC repo), the DMD testsuite (tests/d2/dmd-testsuite) and the druntime stand-alone tests (runtime/druntime/test, Makefile-based). E.g., C and C++ ABI interop issues hardly show up with the defaultlib unittests, but with DMD testsuite.

etcimon commented 4 years ago

I never had a core.thread error for iOS but we should support qemu so ill look into that

jacob-carlborg commented 4 years ago

So the core.thread.fiber release unittests are working?

Yes. All unit tests in druntime are working. The ones that are run by the executable that is built by ldc-build-runtime.

Just keep in mind that you guys are testing the druntime/Phobos unittests, but there are way more tests in the whole testsuite

Sure, but we need to start somewhere 😀

jacob-carlborg commented 4 years ago

Can we consider this issue solved? All unit tests for druntime and Phobos are passing. Here are the pull requests involved to implement the issue.

These pull requests have been merged:

https://github.com/dlang/druntime/pull/3004 https://github.com/dlang/druntime/pull/2952 https://github.com/dlang/druntime/pull/2948 https://github.com/dlang/druntime/pull/2910 https://github.com/dlang/phobos/pull/7430 https://github.com/dlang/phobos/pull/7422 https://github.com/dlang/phobos/pull/7355

This pull request is still open. We're waiting for, what seems to be, a bug in the Bitrise CI service. I've reported the issue to Bitrise and they claim they're working on it.

https://github.com/ldc-developers/ldc/pull/3379

Here's LDC 1.21.0-beta1, with initial support for cross-compiling to iOS. Prebuilt druntime and Phobos libraries for iOS ARM64 are included:

https://github.com/ldc-developers/ldc/releases/tag/v1.21.0-beta1

kinke commented 4 years ago

IMO, not until the full testsuite passes, especially C[++] interop, which still needs the AArch64 ABI fixups I'm working on.

jacob-carlborg commented 4 years ago

Ok, I see.

kinke commented 4 years ago

IMO interesting dmd-testsuite tests (all runnable): cpp11.d, cppa.d, cabi1.d, cpp_abi_tests.d, cpp_stdlib.d, ldc_cabi1.d, eh.d. I hope those work with https://github.com/ldc-developers/ldc/pull/3393 (will be cleaned up and is partly upstreamed already).

s-ludwig commented 1 year ago

What's the status of the test suite nowadays? I just stumbled over this and remembered that there is still a rather large bounty on this issue.

jacob-carlborg commented 1 year ago

What's the status of the test suite nowadays

@s-ludwig The status is that the, in the CI pipeline, Xcode cannot find the provisioning profiles, for some reason. These are necessary to deploy the application on to a device. https://app.bitrise.io/build/04278a15-2eed-484b-9437-d71aec33936a

jacob-carlborg commented 1 year ago

I just stumbled over this and remembered that there is still a rather large bounty on this issue.

This issue needs to be resolved for someone to be able to claim the bounty.