diff --git a/README.md b/README.md index 781c8d9..08b7fc5 100644 --- a/README.md +++ b/README.md @@ -49,27 +49,39 @@ $ git submodule update --init --recursive $ tools/build-all -f ``` -You can quickly try the resulting compiler yourself by typing: +You can quickly try the resulting compiler to generate armv7 code by typing: ``` -$ tools/iphoneos-ldc2 -c hello.d +$ tools/iphoneos-ldc2 -arch armv7 -c hello.d ``` This only gives you a .o file but using Xcode and a provisioning profile you could link, codesign, bundle, and run it on an iOS device. A sample Xcode [project](#sample-hellod-project) does just that if you have a provisioning profile. +Without a provisioning profile, you can still try out D with the iOS Simulator. -At this point, you have an LDC toolchain and druntime/phobos built for 32-bit armv7 iOS in `build/ldc`. This ldc2 is actually configured to target all iOS devices from original iPhone (armv6) to iPhone 6 (arm64). My only iOS devices are armv7 so that is the only target being built. Plus, all iOS device from iPhone 3gs, iPod 3, AppleTV and up can run armv7 instructions [(see Device Compatibility)](https://developer.apple.com/library/ios/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/DeviceCompatibilityMatrix/DeviceCompatibilityMatrix.html). The equivalent gcc or clang target is armv7-apple-darwin, but under the hood in LLVM it is really thumbv7-apple-ios with cortex-a8 selected to enable neon and vfp3. - -`iphoneos-ldc2` is nothing more than a script that does this: +To generate code for the iOS Simulator, just change the `-arch` +option: ``` -$ build/ldc/bin/ldc2 -mtriple=thumbv7-apple-ios5 -mcpu=cortex-a8 -c hello.d +$ tools/iphoneos-ldc2 -arch i386 -c hello.d ``` -This script makes it easy to manage compiler defaults. Clang presets many options when compiling for iOS based on the -arch switch but these presets are not in ldc2 main yet. For now I think it is easier to tweak options with the iphoneos-ldc2 script. Eventually ldc2 will be taught the iOS clang preset options for each iOS arch: armv6, armv7, armv7s, and arm64. +Note that if you don't specify `-arch`, the default target is now the i386 +iOS Simulator (used to be armv7). + +At this point, you have an LDC toolchain and universal druntime/phobos libs +in `build/ldc` for 32-bit armv7, armv7s (iPhone 3gs to iPhone 5c), +and i386 iOS Simulator. The compiler can also target armv6 target +(original iPhone and other older devices), but it is left out of the +universal libs to speed build time. Missing is arm64 for iPhone 6 and iPhone 5s, although +these 64-bit devices can run 32-bit instructions too. For more +information +[see Device Compatibility](https://developer.apple.com/library/ios/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/DeviceCompatibilityMatrix/DeviceCompatibilityMatrix.html). -The ldc2 in build/ldc/bin can also target x86 and x86_64. This is for eventual use of the iPhone Simulator. Unfortunately you cannot run LDC compiled source on iPhone Sim yet because ld refuses to link files with OS X thread local variables when targeting iPhone Sim. I assume this is just to prevent running code on the sim that cannot run in iOS. I think we can get around this by using our own ld or using a different TLS approach that ld won't detect. +My only hardware is armv7 so that is all I can really test for the moment. -More will eventually be added to tools. It is could be useful to add tools to your PATH. +`tools/iphoneos-ldc2` is nothing more than a script that redirects to what +is built in `build/ldc/bin/iphoneos-ldc2`. The binaries have a +`iphoneos-` prefix to remind you that the defaut target is iPhoneOS. ## Sample helloD Project [helloD](https://github.com/smolt/ldc-iphone-dev/tree/master/helloD) is a barebones Xcode project with four simple targets. It only uses the console to demonstrate LDC compiled code running on an iOS device. @@ -82,6 +94,9 @@ More will eventually be added to tools. It is could be useful to add tools to y ## Unittests An Xcode project called [unittester](https://github.com/smolt/ldc-iphone-dev/tree/master/unittester) is included that has targets for running the druntime and phobos unittests. Two are D only with output to the console (nothing to see on the iOS device besides a black screen). The other two are simple scrolling text apps that show the D unittest output as it runs. These apps manage the UI with Objective-C and run the D unittests in another thread. +*Note: the following instructions for running unittests are out-of-date +with latest change to build universal libs. Update in process* + You can build and run the console druntime/phobos unittests from the shell. Here I am running on my iPad mini (cortex-a9): ``` @@ -131,8 +146,7 @@ Or what is left to do. In work now: - Make prebuilt binaries -- Ability to run on iPhone Simulator -- Build universal libs (support sim and device in one lib) +- Get arm64 target working - Make symbolic debugging work better - this is much improved since Xcode 6.3.1. - Update to future release LDC 0.16.0 (DMD FE 2.067) diff --git a/helloD/helloD.xcodeproj/project.pbxproj b/helloD/helloD.xcodeproj/project.pbxproj index af8be7b..83e2ea4 100644 --- a/helloD/helloD.xcodeproj/project.pbxproj +++ b/helloD/helloD.xcodeproj/project.pbxproj @@ -37,7 +37,7 @@ outputFiles = ( "${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.o", ); - script = "../tools/iphoneos-ldc2 -v -O${OPTIMIZATION_LEVEL} -c -od=\"${DERIVED_FILES_DIR}\" \"${INPUT_FILE_PATH}\""; + script = "../tools/xc-iphoneos-dc -v"; }; 37FF99AC1A91956E00098723 /* PBXBuildRule */ = { isa = PBXBuildRule; @@ -49,7 +49,7 @@ outputFiles = ( "${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.o", ); - script = "../tools/iphoneos-ldc2 -v -g -O${OPTIMIZATION_LEVEL} -c -od=\"${DERIVED_FILES_DIR}\" \"${INPUT_FILE_PATH}\""; + script = "../tools/xc-iphoneos-dc -v"; }; 37FF99C41A91988600098723 /* PBXBuildRule */ = { isa = PBXBuildRule; @@ -61,7 +61,7 @@ outputFiles = ( "${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.o", ); - script = "../tools/iphoneos-ldc2 -v -O${OPTIMIZATION_LEVEL} -c -od=\"${DERIVED_FILES_DIR}\" \"${INPUT_FILE_PATH}\""; + script = "../tools/xc-iphoneos-dc -v"; }; 37FF99D71A91CE8100098723 /* PBXBuildRule */ = { isa = PBXBuildRule; @@ -73,7 +73,7 @@ outputFiles = ( "${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.o", ); - script = "../tools/iphoneos-ldc2 -v -O${OPTIMIZATION_LEVEL} -c -od=\"${DERIVED_FILES_DIR}\" \"${INPUT_FILE_PATH}\""; + script = "../tools/xc-iphoneos-dc -v"; }; /* End PBXBuildRule section */ @@ -404,9 +404,8 @@ MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; - VALID_ARCHS = armv7; + VALID_ARCHS = "armv7 armv7s"; }; name = Debug; }; @@ -441,10 +440,9 @@ IPHONEOS_DEPLOYMENT_TARGET = 5.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; - VALID_ARCHS = armv7; + VALID_ARCHS = "armv7 armv7s"; }; name = Release; }; diff --git a/iphoneos-apple-support b/iphoneos-apple-support index 98f3dc6..6917c89 160000 --- a/iphoneos-apple-support +++ b/iphoneos-apple-support @@ -1 +1 @@ -Subproject commit 98f3dc63872379d2ae823fb603ed4a933e00bc43 +Subproject commit 6917c89da2824320fcbd5089177e4cb1a9a71164 diff --git a/ldc b/ldc index be94f96..96bf3d3 160000 --- a/ldc +++ b/ldc @@ -1 +1 @@ -Subproject commit be94f966b0449c41e6a9a05811a425d5f7c8a100 +Subproject commit 96bf3d38ae531223a05fa5fdb1bce96506cd6518 diff --git a/tools/iphoneos-ldc2 b/tools/iphoneos-ldc2 index 7a34477..4d0dc54 100755 --- a/tools/iphoneos-ldc2 +++ b/tools/iphoneos-ldc2 @@ -1,34 +1,23 @@ #!/bin/bash -# Little frontend until ldc2 is updated with proper defaults for -# iPhoneOS. Really all this is doing is defaulting -mtriple -# to values in tools/flag. +# Redirect to ldc2 in build/ldc/bin. Tries with and without iphoneos- +# prefix. tooldir=`dirname $BASH_SOURCE[0]` topdir=`cd $tooldir/..; pwd` -source $tooldir/flags # default dflags - case $0 in *-ldc2) prog=ldc2;; *-ldmd2) prog=ldmd2;; esac -[ "$DEBUGGING_SYMBOLS" = YES ] && args="-g" - -for arg in "$@"; do - case $arg in - *-mtriple*) triple=;; - -v|-vv) verbose=1;; - esac -done - -progpath="$topdir/build/ldc/bin/$prog" - -if [ ! -x "$progpath" ]; then - echo >&2 "$progpath does not seem to be built yet" +path="$topdir/build/ldc/bin" +if [ -x "$path/$prog" ]; then + progpath="$path/$prog" +elif [ -x "$path/iphoneos-$prog" ]; then + progpath="$path/iphoneos-$prog" +else + echo >&2 "$prog or iphoneos-$prog do not seem to be built yet" exit 1 fi -cmd="$progpath $triple" -[ "$verbose" ] && echo $cmd $args "$@" -$cmd $args "$@" +exec $progpath "$@" diff --git a/tools/prepmake-ldc b/tools/prepmake-ldc index b211fdd..ddb61c3 100755 --- a/tools/prepmake-ldc +++ b/tools/prepmake-ldc @@ -1,6 +1,6 @@ #!/bin/bash -# configure to build LDC for iPhoneOS armv7 (iPhone 4 and later 32-bit stuff) -# assumes LLVM is already built +# Configure to build LDC with universal libs (druntime/phobos) for +# iPhoneOS 32-bit archtectures. Assumes LLVM is already built # top dir is one up from this script's dir topdir=`dirname $BASH_SOURCE[0]`/.. @@ -8,6 +8,7 @@ topdir=`dirname $BASH_SOURCE[0]`/.. # LLVM_ROOT_DIR must be an absolute path for some reason absolute=`cd $topdir; pwd` llvmdir="$absolute/build/llvm/Release/" +installdir="$absolute/build/install" if [ ! -d "$llvmdir" ]; then echo "Missing $llvmdir" @@ -15,30 +16,16 @@ if [ ! -d "$llvmdir" ]; then exit 1 fi -# Need Xcode with the iPhoneOS SDK -iphonesdk=`xcrun --sdk iphoneos --show-sdk-path` - -if [ -z "$iphonesdk" ]; then - echo "Missing iPhoneOS SDK, can't build C code in druntime/phobos" - exit 1 -fi - -# get cflags, dflags. -# cmake needs dflags to be separated by ';' instead of spaces, so xlate -source $topdir/tools/flags -dflags_cmake=`echo $dflags|tr -s ' ' ';'` - -# What's with all these flags? -# -DUSE_OSX_TARGET_REAL compiles in code to use target's native real type -# # The D versions are to support troubleshooting issues detected by unittest. # # WIP_FloatPrecIssue - work in progress for some floating point # precision problems -cd $topdir/build/ldc && cmake \ --DLLVM_ROOT_DIR=$llvmdir \ --DCMAKE_CXX_FLAGS='-DUSE_OSX_TARGET_REAL' \ --DD_FLAGS="-w;-d;$dflags_cmake;-d-version=WIP_FloatPrecIssue" \ --DTARGET_C_FLAGS="$cflags -isysroot $iphonesdk" \ -../../ldc +cd $topdir/build/ldc && + cmake -DLLVM_ROOT_DIR=$llvmdir \ + -DIPHONEOS_ARCHS='all' \ + -DPROGRAM_PREFIX=iphoneos- \ + -DCMAKE_INSTALL_PREFIX=$installdir \ + -DINCLUDE_INSTALL_DIR=$installdir/import ../../ldc + + diff --git a/tools/xc-iphoneos-dc b/tools/xc-iphoneos-dc new file mode 100755 index 0000000..77e5744 --- /dev/null +++ b/tools/xc-iphoneos-dc @@ -0,0 +1,48 @@ +#!/bin/bash +# Wrapper for iphoneos-ldc2 that converts Xcode Custom Build Rule +# script environment into command line switches. +# +# Output Files should be: +# ${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.o + +# this script is expected to be alongside iphoneos-ldc2 +dir=`dirname $BASH_SOURCE[0]` +bindir=`cd $dir; pwd` +ldc=iphoneos-ldc2 + +# Find the compiler, hopefully right next door +if [ ! -x "$bindir/$ldc" ]; then + echo >&2 "can't find $ldc in $bindir" + exit 1 +fi + +for arg in "$@"; do + case $arg in + -arch) have_arch=1;; + -c) have_c=1;; + -O*) have_O=1;; + -g*) have_g=1;; + -od*) have_od=1;; + -of*) have_of=1;; + -v|-vv) verbose=1;; + *.d) have_dsrc=1;; + esac +done + +args="$bindir/$ldc" +[ -z "$have_arch" -a "$arch" ] && + args="$args -arch $arch" +[ -z "$have_c" ] && + args="$args -c" +[ -z "$have_O" -a "$OPTIMIZATION_LEVEL" ] && + args="$args -O$OPTIMIZATION_LEVEL" +[ -z "$have_g" -a "$DEBUGGING_SYMBOLS" = YES ] && + args="$args -g" +[ -z "$have_od" -a -d "$DERIVED_FILES_DIR" ] && + args="$args -od='$DERIVED_FILES_DIR'" +[ -z "$have_dsrc" -a -f "$INPUT_FILE_PATH" ] && + args="$args '$INPUT_FILE_PATH'" + +eval set $args "$@" +[ "$verbose" ] && echo "$@" +exec "$@" diff --git a/unittester/unittester.xcodeproj/project.pbxproj b/unittester/unittester.xcodeproj/project.pbxproj index 849a844..043993a 100644 --- a/unittester/unittester.xcodeproj/project.pbxproj +++ b/unittester/unittester.xcodeproj/project.pbxproj @@ -48,7 +48,7 @@ outputFiles = ( "${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.o", ); - script = "../tools/iphoneos-ldc2 -v -O${OPTIMIZATION_LEVEL} -c -od=\"${DERIVED_FILES_DIR}\" \"${INPUT_FILE_PATH}\""; + script = "../tools/xc-iphoneos-dc -v"; }; 3781D8A91A9AE0CE00B2C8E6 /* PBXBuildRule */ = { isa = PBXBuildRule; @@ -60,7 +60,7 @@ outputFiles = ( "${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.o", ); - script = "../tools/iphoneos-ldc2 -v -d-version=UnittestMain -O${OPTIMIZATION_LEVEL} -c -od=\"${DERIVED_FILES_DIR}\" \"${INPUT_FILE_PATH}\""; + script = "../tools/xc-iphoneos-dc -v -d-version=UnittestMain"; }; 3781D8D81A9B09D500B2C8E6 /* PBXBuildRule */ = { isa = PBXBuildRule; @@ -72,7 +72,7 @@ outputFiles = ( "${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.o", ); - script = "../tools/iphoneos-ldc2 -v -O${OPTIMIZATION_LEVEL} -c -od=\"${DERIVED_FILES_DIR}\" \"${INPUT_FILE_PATH}\""; + script = "../tools/xc-iphoneos-dc -v"; }; 3781D8EB1A9B0BD600B2C8E6 /* PBXBuildRule */ = { isa = PBXBuildRule; @@ -84,7 +84,7 @@ outputFiles = ( "${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.o", ); - script = "../tools/iphoneos-ldc2 -v -d-version=UnittestMain -O${OPTIMIZATION_LEVEL} -c -od=\"${DERIVED_FILES_DIR}\" \"${INPUT_FILE_PATH}\""; + script = "../tools/xc-iphoneos-dc -v -d-version=UnittestMain"; }; /* End PBXBuildRule section */ @@ -556,7 +556,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; - VALID_ARCHS = armv7; + VALID_ARCHS = "armv7 armv7s"; }; name = Debug; }; @@ -600,7 +600,7 @@ SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; - VALID_ARCHS = armv7; + VALID_ARCHS = "armv7 armv7s"; }; name = Release; };