1 # This file is part of NIT ( http://www.nitlanguage.org ).
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
15 # Templates and other services to create XCode projects
16 module xcode_templates
21 import compiler
::abstract_compiler
24 # Map to identify the PBX file type for a given file extension
25 private var pbx_file_types
: Map[String, String] is lazy
do
26 var map
= new HashMap[String, String]
29 map
["m"] = "sourcecode.c.objc"
30 map
["c"] = "sourcecode.c.c"
31 map
["h"] = "sourcecode.c.h"
32 map
["cpp"] = "sourcecode.cpp.cpp"
33 map
["hpp"] = "sourcecode.cpp.h"
34 map
["vsh"] = "sourcecode.glsl"
35 map
["fsh"] = "sourcecode.glsl"
38 map
["png"] = "image.png"
39 map
["gif"] = "image.gif"
40 map
["jpg"] = "image.jpeg"
41 map
["jpeg"] = "image.jpeg"
42 map
["pdf"] = "image.pdf"
43 map
["ico"] = "image.ico"
46 map
["app"] = "wrapper.application"
47 map
["plist"] = "text.plist.xml"
48 map
["storyboard"] = "file.storyboard"
49 map
["xib"] = "file.xib"
50 map
["xcassets"] = "folder.assetcatalog"
51 map
["xctest"] = "wrapper.cfbundle"
56 # Generator of PBX UUIDs quique to an execution of the compiler
57 private var pbx_uuid_generator
= new PbxUUIDGenerator is lazy
60 # Generator of PBX UUIDs
62 # PBX UUID are composed of 24 hex characters.
63 # They only need to be unique within the same project.
65 # This implementation simply counts upward from 0.
66 class PbxUUIDGenerator
74 var hex_val
= seed
.to_hex
.to_upper
75 return "0"*(24-hex_val
.length
) + hex_val
79 # Reference to a file for the PBX format of a project file
81 # TODO create subclasses for different file types, this is currently for
82 # compilable source files only.
88 # UUID for build elements
89 private var build_uuid
: String = sys
.pbx_uuid_generator
.next_uuid
is lazy
92 private var ref_uuid
: String = sys
.pbx_uuid_generator
.next_uuid
is lazy
94 # Documentation to add besides this file in the template
95 private fun doc
: String do return path
97 # PBX file type for `self`
100 var map
= sys
.pbx_file_types
101 var ext
= path
.file_extension
102 if ext
!= null and map
.keys
.has
(ext
) then return map
[ext
]
106 # PBX description of this file
107 private fun description
: Writable do return """
108 {{{ref_uuid}}} /* {{{doc}}} */ = {
109 isa = PBXFileReference;
111 lastKnownFileType = {{{file_type}}};
113 sourceTree = "<group>";
117 private fun add_to_project
(project
: PbxprojectTemplate)
119 project
.source_files
.add
self
120 project
.files
.add
self
124 # Template for a PBX project file, usually a `project.pbcproj`
126 # This file list all information required to build an XCode project.
127 # It would usually be written and read by XCode.
128 # From the command line, xcodebuild can read this file but not write it.
130 # Information in the file (simplified list):
132 # * Compilable source files
134 # * Build configurations (Release and debug modes, cflags, etc.)
135 # * List of files composing the project
136 class PbxprojectTemplate
139 # Name of the project
142 # All body/implementation source files to be compiled
143 private var source_files
= new Array[PbxFile]
145 # All asset files added to the app package
146 private var asset_files
= new Array[PbxFile]
148 # All files used by this project
149 private var files
= new Array[PbxFile]
151 # Add `file` to this project
152 fun add_file
(file
: PbxFile) do file
.add_to_project
(self)
165 /* Begin PBXBuildFile section */
168 # List build files (compilable sources and assets) with their reference UUID
169 for array
in [source_files
, asset_files
] do for file
in array
do add
"""
170 {{{file.build_uuid}}} /* {{{file.doc}}} */ = {
172 fileRef = {{{file.ref_uuid}}} /* {{{file.doc}}} */;
177 /* End PBXBuildFile section */
179 /* Begin PBXContainerItemProxy section */
180 AF9F83EA1A5F0D21004B62C0 /* PBXContainerItemProxy */ = {
181 isa = PBXContainerItemProxy;
182 containerPortal = AF9F83C41A5F0D21004B62C0 /* Project object */;
184 remoteGlobalIDString = AF9F83CB1A5F0D21004B62C0;
185 remoteInfo = {{{name}}};
187 /* End PBXContainerItemProxy section */
189 /* Begin PBXFileReference section */
190 /* Static generated files */
191 AF9F83CC1A5F0D21004B62C0 /* {{{name}}}.app */ = {
192 isa = PBXFileReference;
193 explicitFileType = wrapper.application;
195 path = {{{name}}}.app;
196 sourceTree = BUILT_PRODUCTS_DIR;
198 AF9F83D01A5F0D21004B62C0 /* Info.plist */ = {
199 isa = PBXFileReference;
200 lastKnownFileType = text.plist.xml;
202 sourceTree = "<group>";
204 AF9F83DE1A5F0D21004B62C0 /* Base */ = {
205 isa = PBXFileReference;
206 lastKnownFileType = file.storyboard;
208 path = Base.lproj/Main.storyboard;
209 sourceTree = "<group>";
211 AF9F83E01A5F0D21004B62C0 /* Images.xcassets */ = {
212 isa = PBXFileReference;
213 lastKnownFileType = folder.assetcatalog;
214 path = Images.xcassets;
215 sourceTree = "<group>";
217 AF9F83E31A5F0D21004B62C0 /* Base */ = {
218 isa = PBXFileReference;
219 lastKnownFileType = file.xib;
221 path = Base.lproj/LaunchScreen.xib;
222 sourceTree = "<group>";
225 /* Changing generated files */
227 # Describe all known files
228 for file
in files
do add file
.description
231 /* End PBXFileReference section */
233 /* Begin PBXFrameworksBuildPhase section */
234 AF9F83C91A5F0D21004B62C0 /* Frameworks */ = {
235 isa = PBXFrameworksBuildPhase;
236 buildActionMask = 2147483647;
239 runOnlyForDeploymentPostprocessing = 0;
241 /* End PBXFrameworksBuildPhase section */
243 /* Begin PBXGroup section */
244 AF9F83C31A5F0D21004B62C0 = {
247 AF9F83CE1A5F0D21004B62C0 /* {{{name}}} */,
248 AF9F83CD1A5F0D21004B62C0 /* Products */,
250 sourceTree = "<group>";
252 AF9F83CD1A5F0D21004B62C0 /* Products */ = {
255 AF9F83CC1A5F0D21004B62C0 /* {{{name}}}.app */,
258 sourceTree = "<group>";
260 AF9F83CE1A5F0D21004B62C0 /* {{{name}}} */ = {
264 # Reference all known files
265 for file
in files
do add
"""
266 {{{file.ref_uuid}}} /* {{{file.doc}}} */,
272 sourceTree = "<group>";
274 AF9F83CF1A5F0D21004B62C0 /* Supporting Files */ = {
277 AF9F83D01A5F0D21004B62C0 /* Info.plist */,
278 AF9F83D11A5F0D21004B62C0 /* main.m */,
280 name = "Supporting Files";
281 sourceTree = "<group>";
283 /* End PBXGroup section */
285 /* Begin PBXNativeTarget section */
286 AF9F83CB1A5F0D21004B62C0 /* {{{name}}} */ = {
287 isa = PBXNativeTarget;
288 buildConfigurationList = AF9F83F31A5F0D21004B62C0 /* Build configuration list for PBXNativeTarget "{{{name}}}" */;
290 AF9F83C81A5F0D21004B62C0 /* Sources */,
291 AF9F83C91A5F0D21004B62C0 /* Frameworks */,
292 AF9F83CA1A5F0D21004B62C0 /* Resources */,
299 productName = {{{name}}};
300 productReference = AF9F83CC1A5F0D21004B62C0 /* {{{name}}}.app */;
301 productType = "com.apple.product-type.application";
303 /* End PBXNativeTarget section */
305 /* Begin PBXProject section */
306 AF9F83C41A5F0D21004B62C0 /* Project object */ = {
309 LastUpgradeCheck = 0610;
311 AF9F83CB1A5F0D21004B62C0 = {
312 CreatedOnToolsVersion = 6.1.1;
316 buildConfigurationList = AF9F83C71A5F0D21004B62C0 /* Build configuration list for PBXProject "{{{name}}}" */;
317 compatibilityVersion = "Xcode 3.2";
318 developmentRegion = English;
319 hasScannedForEncodings = 0;
324 mainGroup = AF9F83C31A5F0D21004B62C0;
325 productRefGroup = AF9F83CD1A5F0D21004B62C0 /* Products */;
329 AF9F83CB1A5F0D21004B62C0 /* {{{name}}} */,
332 /* End PBXProject section */
334 /* Begin PBXResourcesBuildPhase section */
335 AF9F83CA1A5F0D21004B62C0 /* Resources */ = {
336 isa = PBXResourcesBuildPhase;
337 buildActionMask = 2147483647;
340 # Reference all asset files by their build UUID
341 for file
in asset_files
do add
"""
342 {{{file.build_uuid}}} /* {{{file.doc}}} */,
347 runOnlyForDeploymentPostprocessing = 0;
349 /* End PBXResourcesBuildPhase section */
351 /* Begin PBXSourcesBuildPhase section */
352 AF9F83C81A5F0D21004B62C0 /* Sources */ = {
353 isa = PBXSourcesBuildPhase;
354 buildActionMask = 2147483647;
357 # Reference all compilable source files by their build UUID
358 for file
in source_files
do add
"""
359 {{{file.build_uuid}}} /* {{{file.doc}}} */,
363 runOnlyForDeploymentPostprocessing = 0;
365 /* End PBXSourcesBuildPhase section */
367 /* Begin PBXVariantGroup section */
368 AF9F83DD1A5F0D21004B62C0 /* Main.storyboard */ = {
369 isa = PBXVariantGroup;
371 AF9F83DE1A5F0D21004B62C0 /* Base */,
373 name = Main.storyboard;
374 sourceTree = "<group>";
376 AF9F83E21A5F0D21004B62C0 /* LaunchScreen.xib */ = {
377 isa = PBXVariantGroup;
379 AF9F83E31A5F0D21004B62C0 /* Base */,
381 name = LaunchScreen.xib;
382 sourceTree = "<group>";
384 /* End PBXVariantGroup section */
386 /* Begin XCBuildConfiguration section */
387 AF9F83F11A5F0D21004B62C0 /* Debug */ = {
388 isa = XCBuildConfiguration;
390 ALWAYS_SEARCH_USER_PATHS = NO;
391 CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
392 CLANG_CXX_LIBRARY = "libc++";
393 CLANG_ENABLE_MODULES = YES;
394 CLANG_ENABLE_OBJC_ARC = YES;
395 CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
396 CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
397 "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
398 COPY_PHASE_STRIP = NO;
399 ENABLE_STRICT_OBJC_MSGSEND = YES;
400 GCC_C_LANGUAGE_STANDARD = gnu99;
401 GCC_DYNAMIC_NO_PIC = NO;
402 GCC_OPTIMIZATION_LEVEL = 0;
403 GCC_PREPROCESSOR_DEFINITIONS = (
407 GCC_SYMBOLS_PRIVATE_EXTERN = NO;
408 GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
409 GCC_WARN_UNDECLARED_SELECTOR = YES;
410 GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
411 IPHONEOS_DEPLOYMENT_TARGET = 8.1;
412 MTL_ENABLE_DEBUG_INFO = YES;
413 ONLY_ACTIVE_ARCH = YES;
415 TARGETED_DEVICE_FAMILY = "1,2";
419 AF9F83F21A5F0D21004B62C0 /* Release */ = {
420 isa = XCBuildConfiguration;
422 ALWAYS_SEARCH_USER_PATHS = NO;
423 CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
424 CLANG_CXX_LIBRARY = "libc++";
425 CLANG_ENABLE_MODULES = YES;
426 CLANG_ENABLE_OBJC_ARC = YES;
427 CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
428 CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
429 "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
430 COPY_PHASE_STRIP = YES;
431 ENABLE_NS_ASSERTIONS = NO;
432 ENABLE_STRICT_OBJC_MSGSEND = YES;
433 GCC_C_LANGUAGE_STANDARD = gnu99;
434 GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
435 GCC_WARN_UNDECLARED_SELECTOR = YES;
436 GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
437 IPHONEOS_DEPLOYMENT_TARGET = 8.1;
438 MTL_ENABLE_DEBUG_INFO = NO;
440 TARGETED_DEVICE_FAMILY = "1,2";
441 VALIDATE_PRODUCT = YES;
445 AF9F83F41A5F0D21004B62C0 /* Debug */ = {
446 isa = XCBuildConfiguration;
448 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
449 INFOPLIST_FILE = {{{name}}}/Info.plist;
450 LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
451 PRODUCT_NAME = "$(TARGET_NAME)";
455 AF9F83F51A5F0D21004B62C0 /* Release */ = {
456 isa = XCBuildConfiguration;
458 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
459 INFOPLIST_FILE = {{{name}}}/Info.plist;
460 LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
461 PRODUCT_NAME = "$(TARGET_NAME)";
465 /* End XCBuildConfiguration section */
467 /* Begin XCConfigurationList section */
468 AF9F83C71A5F0D21004B62C0 /* Build configuration list for PBXProject "{{{name}}}" */ = {
469 isa = XCConfigurationList;
470 buildConfigurations = (
471 AF9F83F11A5F0D21004B62C0 /* Debug */,
472 AF9F83F21A5F0D21004B62C0 /* Release */,
474 defaultConfigurationIsVisible = 0;
475 defaultConfigurationName = Release;
477 AF9F83F31A5F0D21004B62C0 /* Build configuration list for PBXNativeTarget "{{{name}}}" */ = {
478 isa = XCConfigurationList;
479 buildConfigurations = (
480 AF9F83F41A5F0D21004B62C0 /* Debug */,
481 AF9F83F51A5F0D21004B62C0 /* Release */,
483 defaultConfigurationIsVisible = 0;
485 /* End XCConfigurationList section */
487 rootObject = AF9F83C41A5F0D21004B62C0 /* Project object */;
493 # Template for a property list used by XCode for iOS projects
497 # Value of CFBundleName, pretty name of the application
498 var product_name
: String
500 # Value of CFBundleIdentifier, namespace of the app
501 var bundle_identifier
: String
503 # Value of CFBundleShortVersionString, human readable version
504 var short_version
: String
506 # Value of CFBundleVersion, often a revision number
507 var bundle_version
: String
512 <?xml version="1.0" encoding="UTF-8"?>
513 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
514 <plist version="1.0">
516 <key>CFBundleDevelopmentRegion</key>
518 <key>CFBundleExecutable</key>
519 <string>$(EXECUTABLE_NAME)</string>
520 <key>CFBundleIdentifier</key>
521 <string>{{{bundle_identifier}}}</string>
522 <key>CFBundleInfoDictionaryVersion</key>
524 <key>CFBundleName</key>
525 <string>{{{product_name}}}</string>
526 <key>CFBundlePackageType</key>
527 <string>APPL</string>
528 <key>CFBundleShortVersionString</key>
529 <string>{{{short_version}}}</string>
530 <key>CFBundleSignature</key>
531 <string>\\?\\?\\?\\?</string>
532 <key>CFBundleVersion</key>
533 <string>{{{bundle_version}}}</string>
534 <key>LSRequiresIPhoneOS</key>
536 <key>UIRequiredDeviceCapabilities</key>
538 <string>armv7</string>
540 <key>UISupportedInterfaceOrientations</key>
542 <string>UIInterfaceOrientationPortrait</string>
543 <string>UIInterfaceOrientationLandscapeLeft</string>
544 <string>UIInterfaceOrientationLandscapeRight</string>
546 <key>UISupportedInterfaceOrientations~ipad</key>
548 <string>UIInterfaceOrientationPortrait</string>
549 <string>UIInterfaceOrientationPortraitUpsideDown</string>
550 <string>UIInterfaceOrientationLandscapeLeft</string>
551 <string>UIInterfaceOrientationLandscapeRight</string>