Skip to content

Latest commit

 

History

History
251 lines (214 loc) · 7.4 KB

cross-compile-pony.org

File metadata and controls

251 lines (214 loc) · 7.4 KB

Cross Compile Pony

Tools Needed

  1. Docker
  2. Emacs with org-mode (to edit this document)

Create the Build Files

This is a literate code document. In Emacs you can run =C-C C-V t= to generate the build files for the Docker container.

Start Container Definition

We are starting from a ubuntu:vivid base image and define a maintainer for this container image.

FROM ubuntu:vivid
MAINTAINER Markus Fix <lispmeister@gmail.com>

Check Number of Bits

This is a 64 bit image which will be important later when we cross compile.

RUN echo "Is this a 32 or 64 bit platform: `/usr/bin/getconf LONG_BIT`"

Install dependencies

Define the base image and install all packages our Pony build depends on. We order the packages alphabetically to make it easir to patch the list of packages later.

RUN dpkg --add-architecture i386
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    automake \
    autotools-dev \
    build-essential \
    g++-multilib \
    gcc-multilib \
    git \
    libicu-dev:i386 \
    libncurses5-dev \
    libncurses5-dev:i386 \
    libpcre3 \
    libssl-dev \
    libxml2-dev:i386 \
    llvm-3.6:i386 \
    llvm:i386 \
    zlib1g-dev:i386 

Install GCC Cross Compiler for ARM

RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    software-properties-common
RUN add-apt-repository -y ppa:linaro-maintainers/toolchain
RUN dpkg --add-architecture armhf
RUN grep -i '^deb http' /etc/apt/sources.list | \
    sed -e 's/archive/ports/' -e 's!/ubuntu!/ubuntu-ports!' \
    -e 's/deb http/deb [arch=armhf] http/' | \
    tee /etc/apt/sources.list.d/armhf.list
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    libicu-dev:armhf \
    libncurses5-dev:armhf \
    libxml2-dev:armhf \
    llvm-3.6:armhf \
    llvm:armhf \
    zlib1g-dev:armhf
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    gcc-arm-linux-gnueabihf \
    g++-arm-linux-gnueabihf

Cleanup

Save some space on the image by removing the apt cache.

RUN apt-get clean && rm -rf /var/lib/apt/lists/*

Create Patches

diff --git Makefile Makefile
index fdae42b..f81e854 100644
--- Makefile
+++ Makefile
@@ -36,6 +36,7 @@ endif
 # Default settings (silent debug build).
 config ?= debug
 arch ?= native
+bits ?= $(shell getconf LONG_BIT)

 ifndef verbose
   SILENT = @
@@ -76,7 +77,7 @@ ALL_CFLAGS = -std=gnu11 -fexceptions \
 ALL_CXXFLAGS = -std=gnu++11 -fno-rtti

 # Determine pointer size in bits.
-BITS := $(shell getconf LONG_BIT)
+BITS := $(bits)

 ifeq ($(BITS),64)
        BUILD_FLAGS += -mcx16

Fetch

RUN rm -rf /build/*
RUN mkdir -p /build/pony
RUN mkdir -p /build/arm
WORKDIR /build/arm
RUN git clone https://github.com/ponylang/ponyc.git

Patch

WORKDIR /build/arm/ponyc
COPY ponyc_armcc.patch /build/pony
RUN patch -p0 < /build/pony/ponyc_armcc.patch

Build Pony RT for ARM

Cross compile the Pony RT library.

RUN CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ \
    make arch=armv7-a bits=32 verbose=true libponyrt

Patch

diff --git Makefile Makefile
index fdae42b..376acde 100644
--- Makefile
+++ Makefile
@@ -36,6 +36,7 @@ endif
 # Default settings (silent debug build).
 config ?= debug
 arch ?= native
+bits ?= $(shell getconf LONG_BIT)
 
 ifndef verbose
   SILENT = @
@@ -67,16 +68,16 @@ prefix ?= /usr/local
 destdir ?= $(prefix)/lib/pony/$(tag)
 
 LIB_EXT ?= a
-BUILD_FLAGS = -march=$(arch) -Werror -Wconversion \
+BUILD_FLAGS = -m$(bits) -march=$(arch) -Werror -Wconversion \
   -Wno-sign-conversion -Wextra -Wall
 LINKER_FLAGS = -march=$(arch)
 AR_FLAGS = -rcs
-ALL_CFLAGS = -std=gnu11 -fexceptions \
+ALL_CFLAGS = -m$(bits) -std=gnu11 -fexceptions \
   -DPONY_VERSION=\"$(tag)\" -DPONY_COMPILER=\"$(CC)\" -DPONY_ARCH=\"$(arch)\"
-ALL_CXXFLAGS = -std=gnu++11 -fno-rtti
+ALL_CXXFLAGS = -m$(bits) -std=gnu++11 -fno-rtti
 
 # Determine pointer size in bits.
-BITS := $(shell getconf LONG_BIT)
+BITS := $(bits)
 
 ifeq ($(BITS),64)
        BUILD_FLAGS += -mcx16
diff --git src/libponyc/codegen/codegen.c src/libponyc/codegen/codegen.c
index c9ce8dc..a94bef0 100644
--- src/libponyc/codegen/codegen.c
+++ src/libponyc/codegen/codegen.c
@@ -452,6 +452,7 @@ bool codegen_init(pass_opt_t* opt)
   LLVMInitializeNativeTarget();
   LLVMInitializeAllTargets();
   LLVMInitializeAllTargetMCs();
+  LLVMInitializeAllTargetInfos();
   LLVMInitializeAllAsmPrinters();
   LLVMInitializeAllAsmParsers();
   LLVMEnablePrettyStackTrace();
diff --git src/libponyc/codegen/genprim.c src/libponyc/codegen/genprim.c
index 8afbd81..b9cfe7d 100644
--- src/libponyc/codegen/genprim.c
+++ src/libponyc/codegen/genprim.c
@@ -690,7 +690,7 @@ static void fp_as_bits(compile_t* c)
 
 static void make_cpuid(compile_t* c)
 {
-#ifdef PLATFORM_IS_X86
+#if 0 // PLATFORM_IS_X86
   LLVMTypeRef elems[4] = {c->i32, c->i32, c->i32, c->i32};
   LLVMTypeRef r_type = LLVMStructTypeInContext(c->context, elems, 4, false);
   LLVMTypeRef f_type = LLVMFunctionType(r_type, &c->i32, 1, false);
@@ -713,7 +713,7 @@ static void make_cpuid(compile_t* c)
 
 static void make_rdtscp(compile_t* c)
 {
-#ifdef PLATFORM_IS_X86
+#if 0 // PLATFORM_IS_X86
   // i64 @llvm.x86.rdtscp(i8*)
   LLVMTypeRef f_type = LLVMFunctionType(c->i64, &c->void_ptr, 1, false);
   LLVMValueRef rdtscp = LLVMAddFunction(c->module, "llvm.x86.rdtscp", f_type);

Patch

rm -rf /home/vagrant/ponyc
cd /home/vagrant
git clone https://github.com/ponylang/ponyc.git
cd /home/vagrant/ponyc
patch -p0 < /vagrant/pony/ponyc_cross_compiler.patch

Build

Build hacked ponyc (based on: https://bluishcoder.co.nz/2015/12/17/cross-compile-pony-programs-for-android.html) for cross compiling pony code for armhf:

CXX="g++ -m32" make bits=32 verbose=true ponyc

Install Pony Binary

We’d like to have a minimized container. Do a bit of cleanup (removing Pony sources) and then install the compiler and rt library. Add a convenience script to call the compiler from outside the container.