Git Product home page Git Product logo

opam-cross-ios's Introduction

opam-cross-ios

This OPAM 2.0 repository contains an up-to-date iOS toolchain featuring OCaml 4.14.0 and 5.0.0 (as well as 4.07.1, 4.04.0) and some commonly used packages.

The supported build system is macOS 10.9 and later. The supported target systems are 32-bit and 64-bit x86 iOS simulator, ARM iOS devices, and Mac Catalyst.

Installation

For 64-bit ios device and simulator cross-compiling, switch to a regular OCaml compiler. Its version must match the version of the cross-compiler:

opam switch 4.14.0
eval `opam config env`

Add this repository to OPAM:

opam repository add ios git://github.com/ocaml-cross/opam-cross-ios

Configure the compiler for 64-bit ARM device:

ARCH=arm64 SUBARCH=arm64 PLATFORM=iPhoneOS SDK=$(xcrun --sdk iphoneos --show-sdk-version) VER=12.0 \
  opam install conf-ios

or for the ios simulator:

ARCH=amd64 SUBARCH=x86_64 PLATFORM=iPhoneSimulator SDK=$(xcrun --sdk iphonesimulator --show-sdk-version) VER=12.0 \
  opam install conf-ios

or for Mac Catalyst:

opam install conf-maccatalyst
ARCH=amd64 SUBARCH=x86_64 PLATFORM=MacOSX SDK=12.3 VER=15.0 opam install conf-ios

32-bit ios device cross-compiling is only supported in OCaml 4.04.0. Switch to a 32-bit compiler when compiling for 32-bit targets:

opam switch 4.04.0+32bit
eval `opam config env`

Configure the compiler for 32-bit ARM:

ARCH=arm SUBARCH=armv7s PLATFORM=iPhoneOS SDK=$(xcrun --sdk iphoneos --show-sdk-version) VER=9.0 \
  opam install conf-ios

... for 32-bit x86:

ARCH=i386 SUBARCH=i386 PLATFORM=iPhoneSimulator SDK=16.0 VER=12.0 \
  opam install conf-ios

Some options can be further tweaked:

  • SUBARCH (when ARCH=arm) specifies the ARM architecture version, one of armv6, armv7, and armv7s;
  • SDK specifies the SDK being used as well as the minimum iOS version on which the compiled code will run;
  • VER specifies the value of the -miphoneos-version-min compiler switch.

The options above (ARCH, SUBARCH, PLATFORM, SDK) are recorded inside the conf-ios package, so make sure to reinstall that package if you wish to switch to a different toolchain. Otherwise, it is not necessary to supply them while upgrading the ocaml-ios* packages.

If desired, request the compiler to be built with flambda optimizers:

opam install conf-flambda-ios

Install the compiler and some packages:

opam install ocaml-ios re-ios

Write some code using them:

let () =
  let regexp = Re.Pcre.regexp {|\b([a-z]+)\b|} in
  let result = Re.exec regexp "Hello, world!" in
  Format.printf "match: %s\n" (Re.Group.get result 1)

Make an object file out of it, link libasmrun.a to your final executable, and link it with your iOS project (you'll need to call caml_startup(argv) to run OCaml code; see this article):

ocamlfind -toolchain ios ocamlopt -package re.pcre -linkpkg -output-complete-obj test_pcre.ml -o test_pcre.o

With opam-ios, cross-compilation is easy!

Managing deployment targets

Generally, any native iOS library would have to be compiled four times: for 32-bit and 64-bit device and simulator. OPAM offers no help here; due to the way OPAM packages currently work, the only realistic option is to create four switches, one switch per target, and build everything four times. To assist with this, a script called ioscaml.sh is distributed in this repository.

The script is supposed to be loaded into a running shell by sourcing it and it defines several functions:

  • ioscaml_create_switches creates four OPAM switches with predefined names;
  • ioscaml_foreach cmd... runs cmd... in every OPAM switch;
  • SDK=9.3 VER=8.0 ioscaml_configure installs conf-ios with appropriate parameters and specified SDK version as well as -miphoneos-version-min in every switch;
  • ioscaml_ocamlbuild runs ocamlbuild once with every OPAM switch selected and places the build products in _build_arm for 32-bit iOS, _build_arm64 for 64-bit iOS, _build_i386 for 32-bit simulator, and _build_amd64 for 64-bit simulator.

A typical workflow would be as follows:

  • ioscaml_create_switches to create the switches and build the host compilers;
  • SDK=9.3 VER=8.0 ioscaml_foreach ioscaml_configure to configure the cross-compiler in the switches;
  • ioscaml_foreach opam pin ... to pin the necessary dependencies;
  • ioscaml_foreach opam install re-ios ... to install the dependencies of your library;
  • ioscaml_foreach ioscaml_ocamlbuild libiosthing.o to build your library.

Porting packages

OCaml packages often have components that execute at compile-time (camlp4 or ppx syntax extensions, cstubs, OASIS, ...). Thus, it is not possible to just blanketly cross-compile every package in the OPAM repository; sometimes you would even need a cross-compiled and a non-cross-compiled package at once. The package definitions also often need package-specific modification in order to work.

As a result, if you want a package to be cross-compiled, you have to copy the definition from opam-repository, rename the package to add -ios suffix while updating any dependencies it could have, and update the build script. Don't forget to add ocaml-ios as a dependency!

Findlib 1.5.4 adds a feature that makes porting packages much simpler; namely, an OCAMLFIND_TOOLCHAIN environment variable that is equivalent to the -toolchain command-line flag. Now it is not necessary to patch the build systems of the packages to select the iOS toolchain; it is often enough to add ["env" "OCAMLFIND_TOOLCHAIN=ios" make ...] to the build command in the opam file.

Note that iOS does not support dynamic linking, and so package build systems should be instructed to not build plugins (*.cmxs).

For projects using OASIS, the following steps will work:

build: [
  ["env" "OCAMLFIND_TOOLCHAIN=ios"
   "ocaml" "setup.ml" "-configure" "--prefix" "%{prefix}%/ios-sysroot"
                                   "--override" "native_dynlink" "false"]
  ["env" "OCAMLFIND_TOOLCHAIN=ios" "ocaml" "setup.ml" "-build"]
]
install: [
  ["env" "OCAMLFIND_TOOLCHAIN=ios" "ocaml" "setup.ml" "-install"]
]
remove: [["ocamlfind" "-toolchain" "ios" "remove" "pkg"]]
depends: ["ocaml-ios" ...]

For projects installing the files via OPAM's .install files (e.g. topkg), the following steps will work:

build: [["ocaml" "pkg/pkg.ml" "build" "--pinned" "%{pinned}%" "--toolchain" "ios" ]]
install: [["opam-installer" "--prefix=%{prefix}%/ios-sysroot" "pkg.install"]]
remove: [["ocamlfind" "-toolchain" "ios" "remove" "pkg"]]
depends: ["ocaml-ios" ...]

The output of the configure script will be entirely wrong, referring to the host configuration rather than target configuration. Thankfully, it is not actually used in the build process itself, so it doesn't matter.

Internals

The aim of this repository is to build a cross-compiler while altering the original codebase in the minimal possible way. There are no attempts to alter the configure script; rather, the configuration is provided directly. The resulting cross-compiler has several interesting properties:

  • All paths to the iOS toolchain are embedded inside ocamlc and ocamlopt; thus, no knowledge of the iOS toolchain is required even for packages that have components in C, provided they use the OCaml driver to compile the C code. (This is usually the case.)
  • The build system makes several assumptions that are not strictly valid while cross-compiling, mainly the fact that the bytecode the cross-compiler has just built can be ran by the ocamlrun on the build system. Thus, the requirement for a 32-bit build compiler for 32-bit targets, as well as for the matching versions.
  • The .opt versions of the compiler are built using itself, which doesn't work while cross-compiling, so all provided tools are bytecode-based.

Acknowledgements

The OCaml cross-compiler in opam-cross-ios is based on a patchset by Gerd Stolpmann.

License

All files contained in this repository are licensed under the CC0 1.0 Universal license.

References

See also opam-cross-windows and opam-cross-android.

opam-cross-ios's People

Contributors

dboris avatar gerdstolpmann avatar whitequark avatar wokalski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opam-cross-ios's Issues

question about cross for Mac OS from Linux.

Hello, I am not sure if this is the right repo, but is there a plan to support cross-compilation from x64 Linux to x64/arm64 Mac? If there are big obstacles for that is there any description of them to estimate the cost of such support?

What about the reverted scenario of host mac and target linux?

Thank you.

Instructions lead to missing iPhone version.

Here's what gets written to conf-ios when following the instructions in README.md:

If I see how to update the README, or other I'll try to send a PR. Thanks.

arch: "arm64"
subarch: "arm64"
platform: "iPhoneOS"
sdk: "9.3"
sysroot:
  "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk"
cflags:
  "-arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk -miphoneos-version-min="
ldflags:
  "-Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk"
triple: "arm-apple-darwin"
triplereal: "aarch64-apple-darwin"

tgls-ios doesn't seem to install

We tried to install tgls-ios and got the following errors. Please see output below & let me know if you need further details.

--Mark


The following actions will be performed:
  ∗  install tgls-ios 0.8.5

=-=- Gathering sources =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=  🐫 

�[KProcessing  1/1: [tgls-ios: http]
�[K
�[KProcessing  1/1: [tgls-ios: http]
�[K[tgls-ios.0.8.5] http://erratique.ch/software/tgls/releases/tgls-0.8.5.tbz downloaded

=-=- Processing actions -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=  🐫 

�[KProcessing  1/1: [tgls-ios: env ocaml]
�[K[ERROR] The compilation of tgls-ios failed at "env TOPKG_CONF_TOOLCHAIN=ios
        TGLS_HOST_OS=Linux ocaml pkg/pkg.ml build --pinned false --with-gl
        false".

�[KProcessing  1/1: [tgls-ios: ocamlfind ios]
#=== ERROR while installing tgls-ios.0.8.5 ====================================#
# opam-version         1.2.2
# os                   darwin
# command              env TOPKG_CONF_TOOLCHAIN=ios TGLS_HOST_OS=Linux ocaml pkg/pkg.ml build --pinned false --with-gl false
# path                 /Users/mhayden/.opam/ios32/build/tgls-ios.0.8.5
# compiler             4.04.0+32bit
# exit-code            1
# env-file             /Users/mhayden/.opam/ios32/build/tgls-ios.0.8.5/tgls-ios-8216-d2c37b.env
# stdout-file          /Users/mhayden/.opam/ios32/build/tgls-ios.0.8.5/tgls-ios-8216-d2c37b.out
# stderr-file          /Users/mhayden/.opam/ios32/build/tgls-ios.0.8.5/tgls-ios-8216-d2c37b.err
### stdout ###
# ocamlfind ocamlopt unix.cmxa -I /Users/mhayden/.opam/ios32/lib/ocamlbuild /Users/mhayden/.opam/ios32/lib/ocamlbuild/ocamlbuildlib.cmxa -linkpkg myocamlbuild.ml /Users/mhayden/.opam/ios32/lib/ocamlbuild/ocamlbuild.cmx -o myocamlbuild
# ocamlfind ocamldep -package ctypes -package bytes -modules src/tgles2.ml > src/tgles2.ml.depends
# + ocamlfind ocamldep -package ctypes -package bytes -modules src/tgles2.ml > src/tgles2.ml.depends
# ocamlfind: Package `ctypes' not found
# Command exited with code 2.
### stderr ###
# pkg.ml: [ERROR] cmd ['ocamlbuild' '-use-ocamlfind' '-classic-display' '-tag' 'debug'
# [...]
#      'README.md' 'src/tgles2.a' 'src/tgles2.cmxa' 'src/tgles2.cma'
#      'src/tgles2.cmx' 'src/tgles2.cmi' 'src/tgles2.mli' 'src/tgles3.a'
#      'src/tgles3.cmxa' 'src/tgles3.cma' 'src/tgles3.cmx' 'src/tgles3.cmi'
#      'src/tgles3.mli' 'src/dlltgles2.so' 'src/libtgles2.a' 'src/dlltgles3.so'
#      'src/libtgles3.a' 'src/tgles2_top.a' 'src/tgles2_top.cmxa'
#      'src/tgles2_top.cma' 'src/tgles2_top.cmx' 'src/tgles3_top.a'
#      'src/tgles3_top.cmxa' 'src/tgles3_top.cma' 'src/tgles3_top.cmx'
#      'test/assert_sizes.c' 'test/trigles2.ml' 'test/trigles3.ml'
#      'test/linkgles2.ml' 'test/linkgles3.ml']: exited with 10


�[K

=-=- Error report -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=  🐫 
The following actions failed
  ∗  install tgls-ios 0.8.5
No changes have been performed

arm32 should be armv7

The ioscaml.sh generates an armv7s target for arm32. I believe this should be armv7, as I think Apple requires armv7 and armv7s is optional.

update

Hi, could you please update this project for OCaml 4.04.1+?

updated repo

FYI, I have upgraded this repo to OPAM 2.0 format, added new versions of cross toolchains, and ported extra packages in dboris/opam-cross-ios. Let me know if you are interested in some or all of these changes, and I can submit a PR.

Xcode 9 "prohibits" use of system() on IOS

See output below for build with ios32.

The definition in stdlib.h for system is as follows:

__swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable")
__API_AVAILABLE(macos(10.0)) __IOS_PROHIBITED
__WATCHOS_PROHIBITED __TVOS_PROHIBITED
int system(const char *) __DARWIN_ALIAS_C(system);

clang -arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.0.sdk -miphoneos-version-min=9.0 -O2 -DCAML_NAME_SPACE -Wall -c -o sys.o sys.c

stderr

[...]

./caml/misc.h:142:34: note: expanded from macro 'CAML_SYS_SYSTEM'

#define CAML_SYS_SYSTEM(command) system(command)

^

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.0.sdk/usr/include/stdlib.h:195:6: note: 'system' has been explicitly marked unavailable here

int system(const char *) __DARWIN_ALIAS_C(system);

^

1 error generated.

make[2]: *** [sys.o] Error 1

make[1]: *** [coldstart] Error 2

make: *** [world] Error 2

ocaml-ios install error

Would love to get some guidance how to resolve the following error:

opam install ocaml-ios re-ios
The following dependencies couldn't be met:
  - ocaml-ios → ocaml-ios32
      unmet availability conditions: conf-ios:arch = "arm" | conf-ios:arch = "i386"
  - ocaml-ios → ocaml-ios64
      unmet availability conditions: conf-ios:arch = "arm64" | conf-ios:arch = "amd64"

No solution found, exiting

Cannot get C runtime compiled

I try to get a simple example from http://www.mega-nerd.com/erikd/Blog/CodeHacking/Ocaml/index.html running on iOS but end up with the following error:
screen shot 2017-07-20 at 10 33 29

To my XCode configuration:
I added /Users/sascha/.opam/4.04.0+ios+amd64/ios-sysroot/lib/ocaml/ to my library and header search paths and added libasmrun.a from /Users/sascha/.opam/4.04.0+ios+amd64/ios-sysroot/lib/ocaml/ as a library to XCode.

To install everything I followed your readme instructions,

Any assistance would be greatly appreciated!

Support for Apple Silicon

I am attempting to follow the instructions in the readme and get the following errors for opam install ocaml-ios re-ios:

  * Missing dependency:
    - ocaml-ios → ocaml-ios64 >= 5.0.0
    unmet availability conditions: 'arch = "x86_64"'

I deviated from the instructions when installing conf-ios by using ARCH=arm64 SUBARCH=arm64 PLATFORM=iPhoneSimulator since the iOS simulator on Apple Silicon is now Arm, not Intel. I assume this is the cause of the errors.

Please take this into account when updating this package.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.