nitc/ios: add LoadingScreen.storyboard
[nit.git] / src / platform / ios.nit
1 # This file is part of NIT ( http://www.nitlanguage.org )
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Compile programs for the iOS platform
16 module ios
17
18 import platform
19 import compiler::abstract_compiler
20 import xcode_templates
21 import app_annotations
22
23 redef class ToolContext
24 redef fun platform_from_name(name)
25 do
26 if name == "ios" then return new IOSPlatform
27 return super
28 end
29 end
30
31 private class IOSPlatform
32 super Platform
33
34 redef fun supports_libunwind do return false
35 redef fun supports_libgc do return false
36 redef fun toolchain(toolcontext, compiler) do return new IOSToolchain(toolcontext, compiler)
37 end
38
39 private class IosProject
40 super AppProject
41
42 redef fun namespace do return super.to_camel_case
43 end
44
45 private class IOSToolchain
46 super MakefileToolchain
47
48 # Root of the iOS project, usually `nit_compile/ios/`
49 var ios_project_root: String is noinit
50
51 # `app.nit` project for the current compilation target
52 var app_project = new IosProject(compiler.modelbuilder, compiler.mainmodule) is lazy
53
54 redef fun default_outname do return "{super}.app"
55
56 # Compile C files in `ios_project_root/app_project.name`
57 redef fun compile_dir
58 do
59 ios_project_root = root_compile_dir/"ios"
60 return ios_project_root/app_project.short_name
61 end
62
63 redef fun write_files(compile_dir, cfiles)
64 do
65 # Clear the project directory before writing anything
66 if ios_project_root.file_exists then ios_project_root.rmdir
67 compile_dir.mkdir
68
69 super
70 end
71
72 redef fun write_makefile(compile_dir, cfiles)
73 do
74 var project_name = app_project.short_name
75
76 # ---
77 # project_folder.xcodeproj (projet meta data)
78
79 # Create an XCode project directory
80 var dir = ios_project_root/project_name+".xcodeproj"
81 if not dir.file_exists then dir.mkdir
82
83 # Create a PBX project file
84 var pbx = new PbxprojectTemplate(project_name)
85
86 ## Register all source files
87 for file in cfiles do pbx.add_file new PbxFile(file)
88 for file in compiler.extern_bodies do
89 pbx.add_file new PbxFile(file.filename.basename)
90 end
91
92 # Basic storyboard, mainly to have the right screen size
93 var launch_screen_storyboard = new LaunchScreenStoryboardTemplate
94 launch_screen_storyboard.title = app_project.name
95 launch_screen_storyboard.subtitle = "app.nit"
96 launch_screen_storyboard.write_to_file ios_project_root / "LaunchScreen.storyboard"
97 pbx.write_to_file dir / "project.pbxproj"
98
99 ## TODO Register asset files
100
101 # ---
102 # project_folder (source code)
103
104 # Create the plist in the same directory as the generated C code
105 if not compile_dir.file_exists then compile_dir.mkdir
106 var plist = new PlistTemplate(app_project.name, app_project.namespace,
107 app_project.version, app_project.version_code.to_s)
108 plist.write_to_file compile_dir/"Info.plist"
109 end
110
111 redef fun compile_c_code(compile_dir)
112 do
113 var project_name = app_project.short_name
114 var release = toolcontext.opt_release.value
115 var outfile = outfile(compiler.mainmodule)
116
117 # Compile with `xcodebuild`
118 #
119 # TODO support more than the iPhone and the simulator.
120 var args = ["sh", "-c", "cd {ios_project_root}; " +
121 "xcodebuild -target '{project_name}' " +
122 "-destination 'platform=iOS Simulator,name=iPhone' " +
123 "-configuration {if release then "Release" else "Debug"} " +
124 "ONLY_ACTIVE_ARCH=NO "+
125 "-sdk iphonesimulator build"]
126 toolcontext.exec_and_check(args, "iOS project error")
127
128 # Move compiled app to destination
129 if outfile.file_exists then outfile.rmdir
130 args = ["mv", "{ios_project_root}/build/Debug-iphonesimulator/{project_name}.app", outfile]
131 toolcontext.exec_and_check(args, "iOS project error")
132 end
133 end