Compile programs for the iOS platform

Introduced classes

private class IOSPlatform

nitc :: IOSPlatform

private class IOSToolchain

nitc :: IOSToolchain

private class IosProject

nitc :: IosProject

Redefined classes

redef class ToolContext

nitc :: ios $ ToolContext

Global context for tools

All class definitions

private class IOSPlatform

nitc $ IOSPlatform

private class IOSToolchain

nitc $ IOSToolchain

private class IosProject

nitc $ IosProject

redef class ToolContext

nitc :: ios $ ToolContext

Global context for tools
package_diagram nitc::ios ios nitc::xcode_templates xcode_templates nitc::ios->nitc::xcode_templates nitc::app_annotations app_annotations nitc::ios->nitc::app_annotations nitc::abstract_compiler abstract_compiler nitc::xcode_templates->nitc::abstract_compiler nitc::parser_util parser_util nitc::app_annotations->nitc::parser_util nitc\>semantize\> semantize nitc::app_annotations->nitc\>semantize\> ...nitc::abstract_compiler ... ...nitc::abstract_compiler->nitc::abstract_compiler ...nitc::parser_util ... ...nitc::parser_util->nitc::parser_util ...nitc\>semantize\> ... ...nitc\>semantize\>->nitc\>semantize\> nitc::compiler compiler nitc::compiler->nitc::ios nitc::nitc nitc nitc::nitc->nitc::compiler nitc::nitc... ... nitc::nitc...->nitc::nitc

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_compiler

nitc :: abstract_compiler

Abstract compiler
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module annotation

nitc :: annotation

Management and utilities on annotations
module array

core :: array

This module introduces the standard array structure.
module auto_super_init

nitc :: auto_super_init

Computing of super-constructors that must be implicitly called at the begin of constructors.
module bitset

core :: bitset

Services to handle BitSet
module bytes

core :: bytes

Services for byte streams and arrays
module c

nitc :: c

Support for nesting C code within a Nit program using its FFI
module c_tools

nitc :: c_tools

provides tools to write C .c and .h files
module caching

serialization :: caching

Services for caching serialization engines
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module console

console :: console

Defines some ANSI Terminal Control Escape Sequences.
module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.
module counter

counter :: counter

Simple numerical statistical analysis and presentation
module csv

csv :: csv

CSV document handling.
module digraph

graph :: digraph

Implementation of directed graphs, also called digraphs.
module engine_tools

serialization :: engine_tools

Advanced services for serialization engines
module environ

core :: environ

Access to the environment variables of the process
module error

core :: error

Standard error-management infrastructure.
module exec

core :: exec

Invocation and management of operating system sub-processes.
module explain_assert_api

nitc :: explain_assert_api

Explain failed assert to the console (service declaration only)
module ffi_base

nitc :: ffi_base

Tools and utilities for implement FFI with different languages
module file

core :: file

File manipulations (create, read, write, etc.)
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module flow

nitc :: flow

Intraprocedural static flow.
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module ini

ini :: ini

Read and write INI configuration files
module inspect

serialization :: inspect

Refine Serializable::inspect to show more useful information
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module kernel

core :: kernel

Most basic classes and methods.
module lexer

nitc :: lexer

Lexer and its tokens.
module lexer_work

nitc :: lexer_work

Internal algorithm and data structures for the Nit lexer
module light_c

nitc :: light_c

Support for nesting C code within a Nit program using its FFI
module light_ffi_base

nitc :: light_ffi_base

Tools and utilities for implement FFI with different languages
module list

core :: list

This module handle double linked lists
module literal

nitc :: literal

Parsing of literal values in the abstract syntax tree.
module loader

nitc :: loader

Loading of Nit source files
module local_var_init

nitc :: local_var_init

Verify that local variables are initialized before their usage
module location

nitc :: location

Nit source-file and locations in source-file
module math

core :: math

Mathematical operations
module mdoc

nitc :: mdoc

Documentation of model entities
module meta

meta :: meta

Simple user-defined meta-level to manipulate types of instances as object.
module mixin

nitc :: mixin

Loading and additional module refinements at link-time.
module mmodule

nitc :: mmodule

modules and module hierarchies in the metamodel
module mmodule_data

nitc :: mmodule_data

Define and retrieve data in modules
module model

nitc :: model

Classes, types and properties
module model_base

nitc :: model_base

The abstract concept of model and related common things
module modelbuilder_base

nitc :: modelbuilder_base

Load nit source files and build the associated model
module modelize

nitc :: modelize

Create a model from nit source files
module modelize_class

nitc :: modelize_class

Analysis and verification of class definitions to instantiate model element
module modelize_property

nitc :: modelize_property

Analysis and verification of property definitions to instantiate model element
module more_collections

more_collections :: more_collections

Highly specific, but useful, collections-related classes.
module mpackage

nitc :: mpackage

Modelisation of a Nit package
module native

core :: native

Native structures for text and bytes
module nitni

nitc :: nitni

Native interface related services (used underneath the FFI)
module nitni_base

nitc :: nitni_base

Native interface related services (used underneath the FFI)
module nitni_callbacks

nitc :: nitni_callbacks

nitni services related to callbacks (used underneath the FFI)
module nitpm_shared

nitc :: nitpm_shared

Services related to the Nit package manager
module numeric

core :: numeric

Advanced services for Numeric types
module opts

opts :: opts

Management of options on the command line
module ordered_tree

ordered_tree :: ordered_tree

Manipulation and presentation of ordered trees.
module parser

nitc :: parser

Parser.
module parser_nodes

nitc :: parser_nodes

AST nodes of the Nit language
module parser_prod

nitc :: parser_prod

Production AST nodes full definition.
module parser_util

nitc :: parser_util

Utils and tools related to parsers and AST
module parser_work

nitc :: parser_work

Internal algorithm and data structures for the Nit parser
module phase

nitc :: phase

Phases of the processing of nit programs
module pkgconfig

nitc :: pkgconfig

Offers the PkgconfigPhase to use the external program "pkg-config" in order
module platform

nitc :: platform

Platform system, used to customize the behavior of the compiler.
module poset

poset :: poset

Pre order sets and partial order set (ie hierarchies)
module protocol

core :: protocol

module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module rapid_type_analysis

nitc :: rapid_type_analysis

Rapid type analysis on the AST
module re

core :: re

Regular expression support for all services based on Pattern
module ropes

core :: ropes

Tree-based representation of a String.
module scope

nitc :: scope

Identification and scoping of local variables and labels.
module semantize

nitc :: semantize

Process bodies of methods in regard with the model.
module serialization

serialization :: serialization

General serialization services
module serialization_core

serialization :: serialization_core

Abstract services to serialize Nit objects to different formats
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module stream

core :: stream

Input and output streams of characters
module tables

nitc :: tables

Module that interfaces the parsing tables.
module template

template :: template

Basic template system
module text

core :: text

All the classes and methods related to the manipulation of text entities
module time

core :: time

Management of time and dates
module toolcontext

nitc :: toolcontext

Common command-line tool infrastructure than handle options and error messages
module typing

nitc :: typing

Intraprocedural resolution of static types and OO-services
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O
module version

nitc :: version

This file was generated by git-gen-version.sh

Parents

module app_annotations

nitc :: app_annotations

Annotations to gather metadata on app.nit projects
module xcode_templates

nitc :: xcode_templates

Templates and other services to create XCode projects

Children

module compiler

nitc :: compiler

Compilation to C

Descendants

module a_star-m

a_star-m

module nitc

nitc :: nitc

A Nit compiler
# Compile programs for the iOS platform
module ios

import platform
import compiler::abstract_compiler
import xcode_templates
import app_annotations

redef class ToolContext
	redef fun platform_from_name(name)
	do
		if name == "ios" then return new IOSPlatform
		return super
	end
end

private class IOSPlatform
	super Platform

	redef fun supports_libunwind do return false
	redef fun supports_libgc do return true
	redef fun toolchain(toolcontext, compiler) do return new IOSToolchain(toolcontext, compiler)
end

private class IosProject
	super AppProject

	redef fun namespace do return super.to_camel_case
end

private class IOSToolchain
	super MakefileToolchain

	# Root of the iOS project, usually `nit_compile/ios/`
	var ios_project_root: String is noinit

	# `app.nit` project for the current compilation target
	var app_project = new IosProject(compiler.modelbuilder, compiler.mainmodule) is lazy

	redef fun default_outname do return "{super}.app"

	private var bdwgc_dir: nullable String = null

	# Compile C files in `ios_project_root/app_project.name`
	redef fun compile_dir
	do
		ios_project_root = root_compile_dir/"ios"
		return ios_project_root/app_project.short_name
	end

	redef fun write_files(compile_dir, cfiles)
	do
		# Clear the project directory before writing anything
		if ios_project_root.file_exists then ios_project_root.rmdir
		compile_dir.mkdir

		# Download the libgc/bdwgc sources
		var nit_dir = toolcontext.nit_dir or else "."
		var share_dir = (nit_dir/"share").realpath
		if not share_dir.file_exists then
			print "iOS project error: Nit share directory not found, please use the environment variable NIT_DIR"
			exit 1
		end

		var bdwgc_dir = "{share_dir}/android-bdwgc/bdwgc"
		self.bdwgc_dir = bdwgc_dir
		if not bdwgc_dir.file_exists then
			toolcontext.exec_and_check(["{share_dir}/android-bdwgc/setup.sh"], "iOS project error")
		end

		super
	end

	redef fun write_makefile(compile_dir, cfiles)
	do
		var project_name = app_project.short_name

		# ---
		# project_folder (source code)

		# Create the plist in the same directory as the generated C code
		if not compile_dir.file_exists then compile_dir.mkdir
		var plist = new PlistTemplate(app_project.name, app_project.namespace,
			app_project.version, app_project.version_code.to_s)
		plist.write_to_file compile_dir/"Info.plist"

		# Copy the folder `ios/AppIcon.appiconset` from the root of the project
		var project_root = "."
		var mpackage = compiler.mainmodule.first_real_mmodule.mpackage
		if mpackage != null then
			var root = mpackage.root
			if root != null then
				var filepath = root.filepath
				if filepath != null then
					project_root = filepath
				end
			end
		end

		# Copy all resources
		var app_files = [project_root]
		app_files.add_all app_project.files

		var icons_found = false

		# Prepare the `Assets.xcassets` folder
		var target_assets_dir = compile_dir / "Assets.xcassets"
		if not target_assets_dir.file_exists then target_assets_dir.mkdir
		"""
{
  "info" : {
	"version" : 1,
	"author" : "nitc"
  }
}""".write_to_file target_assets_dir / "Contents.json"

		(compile_dir / "assets").mkdir

		for path in app_files do

			# Icon
			var icon_dir = path / "ios" / "AppIcon.appiconset"
			if icon_dir.file_exists then
				icons_found = true


				# copy the res folder to the compile dir
				icon_dir = icon_dir.realpath
				toolcontext.exec_and_check(["cp", "-R", icon_dir, target_assets_dir], "iOS project error")
			end

			# Assets
			var assets_dir = path / "assets"
			if assets_dir.file_exists then
				assets_dir = assets_dir.realpath
				toolcontext.exec_and_check(["cp", "-r", assets_dir, compile_dir], "iOS project error")
			end
		end

		# ---
		# project_folder.xcodeproj (projet meta data)

		# Create an XCode project directory
		var dir = ios_project_root/project_name+".xcodeproj"
		if not dir.file_exists then dir.mkdir

		# Create a PBX project file
		var pbx = new PbxprojectTemplate(project_name)

		## Register all source files
		for file in cfiles do pbx.add_file new PbxFile(file)
		for file in compiler.extern_bodies do
			pbx.add_file new PbxFile(file.filename.basename)
		end

		# GC
		if compiler.target_platform.supports_libgc then
			var bdwgc_dir = bdwgc_dir
			assert bdwgc_dir != null

			pbx.cflags = "-I '{bdwgc_dir}/include/' -I '{bdwgc_dir}/libatomic_ops/src' -fno-strict-aliasing " +
			"-DWITH_LIBGC -DNO_EXECUTE_PERMISSION -DALL_INTERIOR_POINTERS -DGC_NO_THREADS_DISCOVERY -DNO_DYLD_BIND_FULLY_IMAGE " +
			"-DGC_DISABLE_INCREMENTAL -DGC_THREADS -DUSE_MMAP -DUSE_MUNMAP -DGC_GCJ_SUPPORT -DJAVA_FINALIZATION "

			var gc_file = new PbxFile("{bdwgc_dir}/extra/gc.c")
			gc_file.cflags = "-Wno-tautological-pointer-compare"
			pbx.add_file gc_file
		end

		# Basic storyboard, mainly to have the right screen size
		var launch_screen_storyboard = new LaunchScreenStoryboardTemplate
		launch_screen_storyboard.title = app_project.name
		launch_screen_storyboard.subtitle = "app.nit"
		launch_screen_storyboard.write_to_file ios_project_root / "LaunchScreen.storyboard"

		# Register the Assets.xcassets folder in the project description
		if icons_found then
			var xcassets = new PbxFile("Assets.xcassets")
			pbx.add_file xcassets
		end

		pbx.write_to_file dir / "project.pbxproj"
	end

	redef fun compile_c_code(compile_dir)
	do
		var project_name = app_project.short_name
		var release = toolcontext.opt_release.value
		var outfile = outfile(compiler.mainmodule)

		# Compile with `xcodebuild`
		#
		# TODO support more than the iPhone and the simulator.
		var compile_mode = if release then "Release" else "Debug"
		var args = ["sh", "-c", "cd {ios_project_root}; " +
			"xcodebuild -quiet -target '{project_name}' " +
			"-destination 'platform=iOS Simulator,name=iPhone' " +
			"-configuration {compile_mode} " +
			 "ONLY_ACTIVE_ARCH=NO "+
			"-sdk iphonesimulator build"]
		toolcontext.exec_and_check(args, "iOS project error")

		# Move compiled app to destination
		if outfile.file_exists then
			var error = outfile.rmdir
			if error != null then
				print_error error
				exit 1
			end
		end

		args = ["mv", "{ios_project_root}/build/{compile_mode}-iphonesimulator/{project_name}.app", outfile]
		toolcontext.exec_and_check(args, "iOS project error")
	end
end
src/platform/ios.nit:15,1--229,3