Cross-compiling (nearly) everything for RPi from OSX


(Karl) #1

I’ve managed to cross-compile the swift tools for the Raspberry Pi from OSX.

I thought I’d share my changes. Branch is here: https://github.com/karwa/swift. I’ll work on merging it soon.

The only real change we need is a bit more structure to the install locations. I want to install to a deployment-target specific subdirectory within INSTALL_DESTDIR. We need that if we have multiple sets of tools to install and packages to build. Installable-package also gets appended with the deployment target and “.tar”.

Does anybody (or any bots) install directly from the build script? Would it be a lot of trouble to give install-destdir and install-symroot a bit of structure?

clang, swift, stdlib, the GlibC overlay all work (although I still need to add a step which regenerates glibc.modulemap - right now you’ll have to find/replace to take your sysroot out of it). LLBuild works. Foundation doesn’t cross-compile just yet, but I built it natively with the resulting swift compiler and clang. The problem seems to be fixable by tweaking the clang headers inside of lib/swift, so I’m not sure if maybe my system headers are a bit wonky. Swiftpm depends on Foundation, and LLDB was having some trouble finding libraries for python.

Invoke with:

../swift/utils/build-script -R \
  --llbuild \
  --ios \
  --installable-package=“${out_files}/swift-3.0" \
  --install-destdir=“${out_files}/output" \
  --install-symroot=“${out_files}/debug-output" \
  -- \
  --llvm-install-components="clang;clang-headers;libclang;libclang-headers" \
  --swift-install-components="compiler;stdlib;sdk-overlay;clang-builtin-headers;editor-integration;sourcekit-xpc-service" \
  --darwin-toolchain-name="swift-3.0" \
  --darwin_toolchain_display_name="local.swift.3" \
  --darwin_toolchain_bundle_identifier="local.swift.3" \
  --toolchain_prefix="swift3.xctoolchain" \
  --darwin_toolchain_alias="local" \
  --install-swift="1" \
  --install-llbuild="1" \
  --install-prefix="/usr" \
  --cross-compile-tools-deployment-targets=linux-armv7 \
  --cross-compile-sysroot="${sysroot}" \
  --cross-compile-toolchain-bin="${toolchain}” \

where ${out_files} is going to end up like this:

— swift-3.0-macosx-x86_64.tar
— swift-3.0-linux-armv7.tar
— output/
   > — macosx-x86_64/
      > — swift3.xctoolchain/
         > — Info.plist
         > — usr/ (etc)
   > — linux-armv7/
      > — usr/ (etc)

${toolchain}:

Built from: https://launchpad.net/gcc-arm-embedded/5.0/5-2015-q4-major
Edit install_toolchain.sh and add “--enable-gold” to the binutils flags
Also in install_common.sh, charged TARGET to "arm-linux-eabi”, but not sure that’s necessary.
Give the path to the unprefixed versions of the tools, e.g: “/cc-toolchain/gcc-arm-none-eabi-5_2-2015q4/install-native/arm-linux-eabi/bin"

${sysroot}:

Created using this script. Requires dpkg-deb (can be installed with brew): https://gist.github.com/karwa/c73f9fd2768c96f6871be4aae152b264

./make_sysroot.py --distro debian --version jessie --arch armhf --install sysroot.armhf.debian.jessie

Let me know how it goes.

Karl


(Dmitri Gribenko) #2

Yes, that's how all Swift builds are done.

Dmitri

···

On Mon, May 9, 2016 at 7:11 PM, Karl Wagner via swift-dev <swift-dev@swift.org> wrote:

Does anybody (or any bots) install directly from the build script?

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Karl) #3

In order for CoreFoundation to build on my Debian machine, I had to edit the Clang headers inside lib/swift/clang - specifically stdarg.h, and add the following line in order for Clang to follow the typedefs and figure that all va_list candidates were the same type:

#ifndef _VA_LIST
#include <_G_config.h> <——— must precede the typedef
typedef __builtin_va_list va_list;
#define _VA_LIST
#endif

Should the clang headers incorporate this, or does anybody know if my system headers are supposed to be including it themselves somewhere?

···

On 10 May 2016, at 04:11, Karl Wagner <razielim@gmail.com> wrote:

I’ve managed to cross-compile the swift tools for the Raspberry Pi from OSX.

I thought I’d share my changes. Branch is here: https://github.com/karwa/swift. I’ll work on merging it soon.

The only real change we need is a bit more structure to the install locations. I want to install to a deployment-target specific subdirectory within INSTALL_DESTDIR. We need that if we have multiple sets of tools to install and packages to build. Installable-package also gets appended with the deployment target and “.tar”.

Does anybody (or any bots) install directly from the build script? Would it be a lot of trouble to give install-destdir and install-symroot a bit of structure?

clang, swift, stdlib, the GlibC overlay all work (although I still need to add a step which regenerates glibc.modulemap - right now you’ll have to find/replace to take your sysroot out of it). LLBuild works. Foundation doesn’t cross-compile just yet, but I built it natively with the resulting swift compiler and clang. The problem seems to be fixable by tweaking the clang headers inside of lib/swift, so I’m not sure if maybe my system headers are a bit wonky. Swiftpm depends on Foundation, and LLDB was having some trouble finding libraries for python.

Invoke with:

../swift/utils/build-script -R \
  --llbuild \
  --ios \
  --installable-package=“${out_files}/swift-3.0" \
  --install-destdir=“${out_files}/output" \
  --install-symroot=“${out_files}/debug-output" \
  -- \
  --llvm-install-components="clang;clang-headers;libclang;libclang-headers" \
  --swift-install-components="compiler;stdlib;sdk-overlay;clang-builtin-headers;editor-integration;sourcekit-xpc-service" \
  --darwin-toolchain-name="swift-3.0" \
  --darwin_toolchain_display_name="local.swift.3" \
  --darwin_toolchain_bundle_identifier="local.swift.3" \
  --toolchain_prefix="swift3.xctoolchain" \
  --darwin_toolchain_alias="local" \
  --install-swift="1" \
  --install-llbuild="1" \
  --install-prefix="/usr" \
  --cross-compile-tools-deployment-targets=linux-armv7 \
  --cross-compile-sysroot="${sysroot}" \
  --cross-compile-toolchain-bin="${toolchain}” \

where ${out_files} is going to end up like this:

— swift-3.0-macosx-x86_64.tar
— swift-3.0-linux-armv7.tar
— output/
   > — macosx-x86_64/
      > — swift3.xctoolchain/
         > — Info.plist
         > — usr/ (etc)
   > — linux-armv7/
      > — usr/ (etc)

${toolchain}:

Built from: https://launchpad.net/gcc-arm-embedded/5.0/5-2015-q4-major
Edit install_toolchain.sh and add “--enable-gold” to the binutils flags
Also in install_common.sh, charged TARGET to "arm-linux-eabi”, but not sure that’s necessary.
Give the path to the unprefixed versions of the tools, e.g: “/cc-toolchain/gcc-arm-none-eabi-5_2-2015q4/install-native/arm-linux-eabi/bin"

${sysroot}:

Created using this script. Requires dpkg-deb (can be installed with brew): https://gist.github.com/karwa/c73f9fd2768c96f6871be4aae152b264

./make_sysroot.py --distro debian --version jessie --arch armhf --install sysroot.armhf.debian.jessie

Let me know how it goes.

Karl


(Karl) #4

My apologies, the correct binutils target for the RPi is “arm-linux-gnueabihf”, not “arm-linux-eabi”, and you do have to change it before building the toolchain.

Karl

···

On 10 May 2016, at 04:11, Karl Wagner <razielim@gmail.com> wrote:

I’ve managed to cross-compile the swift tools for the Raspberry Pi from OSX.

I thought I’d share my changes. Branch is here: https://github.com/karwa/swift. I’ll work on merging it soon.

The only real change we need is a bit more structure to the install locations. I want to install to a deployment-target specific subdirectory within INSTALL_DESTDIR. We need that if we have multiple sets of tools to install and packages to build. Installable-package also gets appended with the deployment target and “.tar”.

Does anybody (or any bots) install directly from the build script? Would it be a lot of trouble to give install-destdir and install-symroot a bit of structure?

clang, swift, stdlib, the GlibC overlay all work (although I still need to add a step which regenerates glibc.modulemap - right now you’ll have to find/replace to take your sysroot out of it). LLBuild works. Foundation doesn’t cross-compile just yet, but I built it natively with the resulting swift compiler and clang. The problem seems to be fixable by tweaking the clang headers inside of lib/swift, so I’m not sure if maybe my system headers are a bit wonky. Swiftpm depends on Foundation, and LLDB was having some trouble finding libraries for python.

Invoke with:

../swift/utils/build-script -R \
  --llbuild \
  --ios \
  --installable-package=“${out_files}/swift-3.0" \
  --install-destdir=“${out_files}/output" \
  --install-symroot=“${out_files}/debug-output" \
  -- \
  --llvm-install-components="clang;clang-headers;libclang;libclang-headers" \
  --swift-install-components="compiler;stdlib;sdk-overlay;clang-builtin-headers;editor-integration;sourcekit-xpc-service" \
  --darwin-toolchain-name="swift-3.0" \
  --darwin_toolchain_display_name="local.swift.3" \
  --darwin_toolchain_bundle_identifier="local.swift.3" \
  --toolchain_prefix="swift3.xctoolchain" \
  --darwin_toolchain_alias="local" \
  --install-swift="1" \
  --install-llbuild="1" \
  --install-prefix="/usr" \
  --cross-compile-tools-deployment-targets=linux-armv7 \
  --cross-compile-sysroot="${sysroot}" \
  --cross-compile-toolchain-bin="${toolchain}” \

where ${out_files} is going to end up like this:

— swift-3.0-macosx-x86_64.tar
— swift-3.0-linux-armv7.tar
— output/
   > — macosx-x86_64/
      > — swift3.xctoolchain/
         > — Info.plist
         > — usr/ (etc)
   > — linux-armv7/
      > — usr/ (etc)

${toolchain}:

Built from: https://launchpad.net/gcc-arm-embedded/5.0/5-2015-q4-major
Edit install_toolchain.sh and add “--enable-gold” to the binutils flags
Also in install_common.sh, charged TARGET to "arm-linux-eabi”, but not sure that’s necessary.
Give the path to the unprefixed versions of the tools, e.g: “/cc-toolchain/gcc-arm-none-eabi-5_2-2015q4/install-native/arm-linux-eabi/bin"

${sysroot}:

Created using this script. Requires dpkg-deb (can be installed with brew): https://gist.github.com/karwa/c73f9fd2768c96f6871be4aae152b264

./make_sysroot.py --distro debian --version jessie --arch armhf --install sysroot.armhf.debian.jessie

Let me know how it goes.

Karl


(Karl) #5

So, while working on this I’ve found some cases where build-script-impl is a bit sloppy about naming: we use the term “deployment target” quite a lot, both when talking about hosts for the swift compiler and standard library targets.

This leads to weird parts of the script - like in testing, where we iterate STDLIB_DEPLOYMENT_TARGETS but skip everything which isn’t also a host. Somebody got confused between deployment targets. Or in the lipo step, where we attempt to merge libraries across different hosts for some reason.

There are other general logic holes - such as the swift build targets getting calculated once in some free-standing code, when really they should be calculated per-host, or executables being looked for in the current host build output (rather than the local host build output).

So I’ve cut away my specific cross-compiling edits from these more general fixes and created a PR for those changes: https://github.com/apple/swift/pull/2497

I know it’s quite a big diff, and that cross-compilation isn’t a massive priority, but I’d really like to incorporate feedback and, if possible, get it merged as soon as possible. No parameters or output has been changed (e.g. the host-specific install locations aren’t in there), so for the case today where you don’t cross-compile the tools, everything should resolve as it does today.

Thanks

Karl

···

On 11 May 2016, at 09:17, Karl <raziel.im+swift-users@gmail.com> wrote:

On 10 May 2016, at 04:11, Karl Wagner <razielim@gmail.com <mailto:razielim@gmail.com>> wrote:

I’ve managed to cross-compile the swift tools for the Raspberry Pi from OSX.

I thought I’d share my changes. Branch is here: https://github.com/karwa/swift. I’ll work on merging it soon.

The only real change we need is a bit more structure to the install locations. I want to install to a deployment-target specific subdirectory within INSTALL_DESTDIR. We need that if we have multiple sets of tools to install and packages to build. Installable-package also gets appended with the deployment target and “.tar”.

Does anybody (or any bots) install directly from the build script? Would it be a lot of trouble to give install-destdir and install-symroot a bit of structure?

clang, swift, stdlib, the GlibC overlay all work (although I still need to add a step which regenerates glibc.modulemap - right now you’ll have to find/replace to take your sysroot out of it). LLBuild works. Foundation doesn’t cross-compile just yet, but I built it natively with the resulting swift compiler and clang. The problem seems to be fixable by tweaking the clang headers inside of lib/swift, so I’m not sure if maybe my system headers are a bit wonky. Swiftpm depends on Foundation, and LLDB was having some trouble finding libraries for python.

Invoke with:

../swift/utils/build-script -R \
  --llbuild \
  --ios \
  --installable-package=“${out_files}/swift-3.0" \
  --install-destdir=“${out_files}/output" \
  --install-symroot=“${out_files}/debug-output" \
  -- \
  --llvm-install-components="clang;clang-headers;libclang;libclang-headers" \
  --swift-install-components="compiler;stdlib;sdk-overlay;clang-builtin-headers;editor-integration;sourcekit-xpc-service" \
  --darwin-toolchain-name="swift-3.0" \
  --darwin_toolchain_display_name="local.swift.3" \
  --darwin_toolchain_bundle_identifier="local.swift.3" \
  --toolchain_prefix="swift3.xctoolchain" \
  --darwin_toolchain_alias="local" \
  --install-swift="1" \
  --install-llbuild="1" \
  --install-prefix="/usr" \
  --cross-compile-tools-deployment-targets=linux-armv7 \
  --cross-compile-sysroot="${sysroot}" \
  --cross-compile-toolchain-bin="${toolchain}” \

where ${out_files} is going to end up like this:

— swift-3.0-macosx-x86_64.tar
— swift-3.0-linux-armv7.tar
— output/
   > — macosx-x86_64/
      > — swift3.xctoolchain/
         > — Info.plist
         > — usr/ (etc)
   > — linux-armv7/
      > — usr/ (etc)

${toolchain}:

Built from: https://launchpad.net/gcc-arm-embedded/5.0/5-2015-q4-major
Edit install_toolchain.sh and add “--enable-gold” to the binutils flags
Also in install_common.sh, charged TARGET to "arm-linux-eabi”, but not sure that’s necessary.
Give the path to the unprefixed versions of the tools, e.g: “/cc-toolchain/gcc-arm-none-eabi-5_2-2015q4/install-native/arm-linux-eabi/bin"

${sysroot}:

Created using this script. Requires dpkg-deb (can be installed with brew): https://gist.github.com/karwa/c73f9fd2768c96f6871be4aae152b264

./make_sysroot.py --distro debian --version jessie --arch armhf --install sysroot.armhf.debian.jessie

Let me know how it goes.

Karl

My apologies, the correct binutils target for the RPi is “arm-linux-gnueabihf”, not “arm-linux-eabi”, and you do have to change it before building the toolchain.

Karl