nitc/ios: use a camel case version of app namespace for some version of XCode
[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 = super/"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 # Create an XCode project directory
77 var dir = ios_project_root/project_name+".xcodeproj"
78 if not dir.file_exists then dir.mkdir
79
80 # Create a PBX project file
81 var pbx = new PbxprojectTemplate(project_name)
82
83 ## Register all source files
84 for file in cfiles do pbx.add_file new PbxFile(file)
85 for file in compiler.extern_bodies do
86 pbx.add_file new PbxFile(file.filename.basename(""))
87 end
88
89 ## TODO Register asset files
90
91 pbx.write_to_file dir/"project.pbxproj"
92
93 # Create the plist in the same directory as the generated C code
94 if not compile_dir.file_exists then compile_dir.mkdir
95 var plist = new PlistTemplate(app_project.name, app_project.namespace,
96 app_project.version, app_project.version_code.to_s)
97 plist.write_to_file compile_dir/"Info.plist"
98 end
99
100 redef fun compile_c_code(compile_dir)
101 do
102 var project_name = app_project.short_name
103 var release = toolcontext.opt_release.value
104 var outfile = outfile(compiler.mainmodule)
105
106 # Compile with `xcodebuild`
107 #
108 # TODO support more than the iPhone and the simulator.
109 var args = ["sh", "-c", "cd {ios_project_root}; " +
110 "xcodebuild -target '{project_name}' " +
111 "-destination 'platform=iOS Simulator,name=iPhone' " +
112 "-configuration {if release then "Release" else "Debug"} " +
113 "-sdk iphonesimulator build"]
114 toolcontext.exec_and_check(args, "iOS project error")
115
116 # Move compiled app to destination
117 if outfile.file_exists then outfile.rmdir
118 args = ["mv", "{ios_project_root}/build/Debug-iphonesimulator/{project_name}.app", outfile]
119 toolcontext.exec_and_check(args, "iOS project error")
120 end
121 end