X-Git-Url: http://nitlanguage.org diff --git a/src/platform/ios.nit b/src/platform/ios.nit index 7ba038b..27979b0 100644 --- a/src/platform/ios.nit +++ b/src/platform/ios.nit @@ -32,7 +32,7 @@ private class IOSPlatform super Platform redef fun supports_libunwind do return false - redef fun supports_libgc do return false + redef fun supports_libgc do return true redef fun toolchain(toolcontext, compiler) do return new IOSToolchain(toolcontext, compiler) end @@ -53,6 +53,8 @@ private class IOSToolchain 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 @@ -66,6 +68,20 @@ private class IOSToolchain 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 @@ -73,6 +89,71 @@ private class IOSToolchain 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 @@ -86,15 +167,33 @@ private class IOSToolchain pbx.add_file new PbxFile(file.filename.basename) end - ## TODO Register asset files + # GC + if compiler.target_platform.supports_libgc then + var bdwgc_dir = bdwgc_dir + assert bdwgc_dir != null - pbx.write_to_file dir/"project.pbxproj" + 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 " - # 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" + 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) @@ -106,17 +205,25 @@ private class IOSToolchain # 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 -target '{project_name}' " + + "xcodebuild -quiet -target '{project_name}' " + "-destination 'platform=iOS Simulator,name=iPhone' " + - "-configuration {if release then "Release" else "Debug"} " + + "-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 outfile.rmdir - args = ["mv", "{ios_project_root}/build/Debug-iphonesimulator/{project_name}.app", outfile] + 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