Merge: app.nit: Intro the `app_files` annotation, and use it in calculator
authorJean Privat <jean@pryen.org>
Wed, 3 Aug 2016 16:38:43 +0000 (12:38 -0400)
committerJean Privat <jean@pryen.org>
Wed, 3 Aug 2016 16:38:43 +0000 (12:38 -0400)
Intro `app_files`, an annotation to specify where to find more Android and iOS specific files. This effectively associates resources to a specific Nit module. It can be used to have different icons per branding, or to package graphical assets with a module from the lib.

It is used in the calculator to assign a different icon to the scientific calculator variant.

Pull-Request: #2228
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Romain Chanoir <romain.chanoir@viacesi.fr>

12 files changed:
examples/calculator/Makefile
examples/calculator/art/icon-ios-sci.svg [new file with mode: 0644]
examples/calculator/art/icon-sci.svg [new file with mode: 0644]
examples/calculator/src/calculator.nit
examples/calculator/src/scientific/android/.gitignore [new file with mode: 0644]
examples/calculator/src/scientific/ios/.gitignore [new file with mode: 0644]
examples/calculator/src/scientific/scientific.nit [moved from examples/calculator/src/scientific_calculator.nit with 90% similarity]
lib/app/README.md
lib/app/app_base.nit
src/platform/android.nit
src/platform/app_annotations.nit
src/platform/ios.nit

index 8265899..bf2a19e 100644 (file)
@@ -7,27 +7,35 @@ bin/calculator: $(shell ${NITLS} -M src/calculator.nit linux) ${NITC}
        mkdir -p bin
        ${NITC} -o $@ src/calculator.nit -m linux
 
-bin/scientific_calculator: $(shell ${NITLS} -M src/scientific_calculator.nit linux) ${NITC}
+bin/scientific: $(shell ${NITLS} -M scientific linux) ${NITC}
        mkdir -p bin
-       ${NITC} -o $@ src/scientific_calculator.nit -m linux
+       ${NITC} -o $@ src/scientific -m linux
 
 # ---
 # Android
 
-android: bin/calculator.apk
+android: bin/calculator.apk bin/scientific.apk
 
-bin/calculator.apk: $(shell ${NITLS} -M src/scientific_calculator.nit src/android_calculator.nit) ${NITC} android/res/
+bin/calculator.apk: $(shell ${NITLS} -M src/android_calculator.nit) ${NITC} android/res/drawable-hdpi/icon.png
        mkdir -p bin
-       ${NITC} -o $@ src/scientific_calculator.nit -m src/android_calculator.nit -D debug
+       ${NITC} -o $@ src/android_calculator.nit -D debug
 
-android-release: $(shell ${NITLS} -M src/scientific_calculator.nit src/android_calculator.nit) ${NITC} android/res/
+bin/scientific.apk: $(shell ${NITLS} -M src/scientific src/android_calculator.nit) ${NITC} src/scientific/android/res/drawable-hdpi/icon.png
        mkdir -p bin
-       ${NITC} -o bin/calculator.apk src/scientific_calculator.nit -m src/android_calculator.nit --release
+       ${NITC} -o $@ src/scientific -m src/android_calculator.nit -D debug
 
-android/res/: art/icon.svg ../../contrib/inkscape_tools/bin/svg_to_icons
+android-release: $(shell ${NITLS} -M src/scientific src/android_calculator.nit) ${NITC} android/res/drawable-hdpi/icon.png
+       mkdir -p bin
+       ${NITC} -o bin/calculator.apk src/scientific -m src/android_calculator.nit --release
+
+android/res/drawable-hdpi/icon.png: art/icon.svg ../../contrib/inkscape_tools/bin/svg_to_icons
        mkdir -p android/res
        ../../contrib/inkscape_tools/bin/svg_to_icons art/icon.svg --android --out android/res/
 
+src/scientific/android/res/drawable-hdpi/icon.png: art/icon_sci.svg ../../contrib/inkscape_tools/bin/svg_to_icons
+       mkdir -p src/scientific/android/res
+       ../../contrib/inkscape_tools/bin/svg_to_icons art/icon-sci.svg --android --out src/scientific/android/res/
+
 ../../contrib/inkscape_tools/bin/svg_to_icons:
        make -C ../../contrib/inkscape_tools/
 
@@ -37,14 +45,24 @@ android-install: bin/calculator.apk
 # ---
 # iOS
 
-bin/calculator.app: $(shell ${NITLS} -M src/scientific_calculator.nit src/ios_calculator.nit) ${NITC} ios/AppIcon.appiconset/Contents.json
+ios: bin/calculator.app bin/scientific.app
+
+bin/calculator.app: $(shell ${NITLS} -M src/ios_calculator.nit) ${NITC} ios/AppIcon.appiconset/Contents.json
        mkdir -p bin
-       ${NITC} -o $@ src/scientific_calculator.nit -m src/ios_calculator.nit -D debug
+       ${NITC} -o $@ src/ios_calculator.nit -D debug
+
+bin/scientific.app: $(shell ${NITLS} -M src/scientific src/ios_calculator.nit) ${NITC} src/scientific/ios/AppIcon.appiconset/Contents.json
+       mkdir -p bin
+       ${NITC} -o $@ src/scientific -m src/ios_calculator.nit -D debug
 
 ios/AppIcon.appiconset/Contents.json: art/icon-ios.svg
        mkdir -p ios
        ../../contrib/inkscape_tools/bin/svg_to_icons art/icon-ios.svg --ios --out ios/AppIcon.appiconset/
 
+src/scientific/ios/AppIcon.appiconset/Contents.json: art/icon-ios.svg
+       mkdir -p ios
+       ../../contrib/inkscape_tools/bin/svg_to_icons art/icon-ios-sci.svg --ios --out src/scientific/ios/AppIcon.appiconset/
+
 # ---
 # Tests
 
diff --git a/examples/calculator/art/icon-ios-sci.svg b/examples/calculator/art/icon-ios-sci.svg
new file mode 100644 (file)
index 0000000..4ff6c5c
--- /dev/null
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="512"
+   height="512"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="icon-ios-sci.svg">
+  <defs
+     id="defs4" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="1"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="388.94406"
+     inkscape:cy="238.25989"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1724"
+     inkscape:window-height="1103"
+     inkscape:window-x="242"
+     inkscape:window-y="23"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-540.36218)">
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:190.84666443px;line-height:125%;font-family:Sathu;-inkscape-font-specification:Sathu;letter-spacing:0px;word-spacing:0px;fill:#008bff;fill-opacity:1;stroke:none"
+       x="285.77982"
+       y="961.64594"
+       id="text3014"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan3016"
+         x="285.77982"
+         y="961.64594">x²</tspan></text>
+    <g
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:269.1137085px;line-height:125%;font-family:'Droid Sans';-inkscape-font-specification:'Droid Sans';letter-spacing:0px;word-spacing:0px;fill:#008bff;fill-opacity:1;stroke:none"
+       id="text3013"
+       transform="translate(4,-4)">
+      <path
+         d="m 77.43458,894.9284 0,-19.57907 121.41654,0 0,19.57907 -121.41654,0 m 0,53.87531 0,-19.71048 121.41654,0 0,19.71048 -121.41654,0"
+         style="fill:#008bff;fill-opacity:1"
+         id="path2999"
+         inkscape:connector-curvature="0" />
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:183.57151794px;line-height:125%;font-family:Sathu;-inkscape-font-specification:Sathu;letter-spacing:0px;word-spacing:0px;fill:#008bff;fill-opacity:1;stroke:none"
+       x="269.98895"
+       y="720.69153"
+       id="text2994"
+       sodipodi:linespacing="125%"
+       transform="scale(0.99205729,1.0080063)"><tspan
+         sodipodi:role="line"
+         id="tspan2996"
+         x="269.98895"
+         y="720.69153">√</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:190.84666443000000413px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#008bff;fill-opacity:1;stroke:none;font-family:Sathu;-inkscape-font-specification:Sathu;"
+       x="67.883858"
+       y="734.41699"
+       id="text2998"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan3000"
+         x="67.883858"
+         y="734.41699">π</tspan></text>
+  </g>
+</svg>
diff --git a/examples/calculator/art/icon-sci.svg b/examples/calculator/art/icon-sci.svg
new file mode 100644 (file)
index 0000000..187bb2d
--- /dev/null
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="512"
+   height="512"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.5 r10040"
+   sodipodi:docname="icon_sci.svg">
+  <defs
+     id="defs4" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="164.13268"
+     inkscape:cy="278.8294"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1598"
+     inkscape:window-height="1316"
+     inkscape:window-x="2649"
+     inkscape:window-y="84"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-540.36218)">
+    <rect
+       style="fill:#4d4d4d;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none"
+       id="rect2987"
+       width="500"
+       height="500"
+       x="5.9999847"
+       y="546.36218"
+       rx="64"
+       ry="64" />
+    <rect
+       ry="48"
+       rx="48"
+       y="569.2193"
+       x="32.42857"
+       height="211.42856"
+       width="211.42856"
+       id="rect2989"
+       style="fill:#cccccc;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none" />
+    <rect
+       style="fill:#cccccc;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none"
+       id="rect2991"
+       width="211.42856"
+       height="211.42856"
+       x="268.14285"
+       y="569.2193"
+       rx="48"
+       ry="48" />
+    <rect
+       style="fill:#cccccc;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none"
+       id="rect2993"
+       width="211.42856"
+       height="211.42856"
+       x="32.42857"
+       y="806.36218"
+       rx="48"
+       ry="48" />
+    <rect
+       ry="48"
+       rx="48"
+       y="806.36218"
+       x="268.14285"
+       height="211.42856"
+       width="211.42856"
+       id="rect2995"
+       style="fill:#cccccc;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none" />
+    <g
+       style="font-size:269.1137085px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Droid Sans;-inkscape-font-specification:Droid Sans"
+       id="text3013">
+      <path
+         d="m 77.43458,894.9284 0,-19.57907 121.41654,0 0,19.57907 -121.41654,0 m 0,53.87531 0,-19.71048 121.41654,0 0,19.71048 -121.41654,0"
+         id="path2999"
+         style="" />
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:190.84666443px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Droid Sans;-inkscape-font-specification:Droid Sans"
+       x="318.1875"
+       y="744.69647"
+       id="text2994"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan2996"
+         x="318.1875"
+         y="744.69647">√</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:190.84666443px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Droid Sans;-inkscape-font-specification:Droid Sans"
+       x="72.978729"
+       y="725.84735"
+       id="text2998"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan3000"
+         x="72.978729"
+         y="725.84735">π</tspan></text>
+    <flowRoot
+       xml:space="preserve"
+       id="flowRoot3002"
+       style="fill:black;stroke:none;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;font-family:New Shape;font-style:normal;font-weight:normal;font-size:16px;line-height:125%;letter-spacing:0px;word-spacing:0px;-inkscape-font-specification:New Shape;font-stretch:normal;font-variant:normal"><flowRegion
+         id="flowRegion3004"><rect
+           id="rect3006"
+           width="104.28571"
+           height="282.85715"
+           x="-225"
+           y="-62.285713" /></flowRegion><flowPara
+         id="flowPara3008"></flowPara></flowRoot>    <text
+       xml:space="preserve"
+       style="font-size:190.84666443px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Droid Sans;-inkscape-font-specification:Droid Sans"
+       x="303.01755"
+       y="973.79059"
+       id="text3014"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan3016"
+         x="303.01755"
+         y="973.79059">x²</tspan></text>
+  </g>
+</svg>
index 3b89ec7..6cfb1aa 100644 (file)
@@ -14,8 +14,8 @@
 
 # Portable calculator UI
 module calculator is
-       app_name "app.nit Calc."
-       app_version(0, 1, git_revision)
+       app_name "app.nit Calc"
+       app_version(0, 2, git_revision)
        app_namespace "org.nitlanguage.calculator"
 
        # Lock in portrait mode
diff --git a/examples/calculator/src/scientific/android/.gitignore b/examples/calculator/src/scientific/android/.gitignore
new file mode 100644 (file)
index 0000000..72e8ffc
--- /dev/null
@@ -0,0 +1 @@
+*
diff --git a/examples/calculator/src/scientific/ios/.gitignore b/examples/calculator/src/scientific/ios/.gitignore
new file mode 100644 (file)
index 0000000..72e8ffc
--- /dev/null
@@ -0,0 +1 @@
+*
 # limitations under the License.
 
 # Extends the portable calculator app with scientific operations
-module scientific_calculator
+module scientific is
+       app_name "app.nit Calc Sci"
+       app_namespace "org.nitlanguage.scientific_calculator"
+       app_files
+end
 
 import calculator
 
index 0e0187b..680c6b9 100644 (file)
@@ -150,6 +150,17 @@ The _app.nit_ framework defines three annotations to customize the application p
   The special function `git_revision` will use the prefix of the hash of the latest git commit.
   By default, the version is 0.1.
 
+* `app_files` tells the compiler where to find platform specific resource files associated to a module.
+  By default, only the root of the project is searched for the folders `android` and `ios`.
+  The `android` folder is used as base for the generated Android project,
+  it can be used to specify the resource files, libs and even Java source files.
+  The `ios` folder is searched for icons only.
+
+  Each argument of `app_files` is a relative path to a folder containing extra `android` or `ios` folders.
+  If there is no arguments, the parent folder of the annotated module is used.
+  In case of name conflicts in the resource files, the files from the project root have the lowest priority,
+  those associated to modules lower in the importation hierarchy have higher priority.
+
 ## Usage Example
 
 ~~~
index e709e84..4e9592c 100644 (file)
@@ -19,6 +19,7 @@ module app_base is
        new_annotation app_name
        new_annotation app_namespace
        new_annotation app_version
+       new_annotation app_files
 end
 
 # App subclasses are cross-platform applications
index 1e89a84..adb9543 100644 (file)
@@ -118,7 +118,6 @@ class AndroidToolchain
                        if f isa ExternCFile then cfiles.add(f.filename.basename)
                end
 
-               # Is there an icon?
                var project_root = "."
                var mpackage = compiler.mainmodule.first_real_mmodule.mpackage
                if mpackage != null then
@@ -131,6 +130,35 @@ class AndroidToolchain
                        end
                end
 
+               # Set the default pretty application name
+"""<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">{{{app_name}}}</string>
+</resources>""".write_to_file "{android_project_root}/res/values/strings.xml"
+
+               # Copy assets, resources and libs where expected by the SDK
+
+               ## Collect path to all possible folder where we can find the `android` folder
+               var app_files = [project_root]
+               app_files.add_all project.files
+
+               for path in app_files do
+                       # Copy the assets folder
+                       var assets_dir = path / "assets"
+                       if assets_dir.file_exists then
+                               assets_dir = assets_dir.realpath
+                               toolcontext.exec_and_check(["cp", "-r", assets_dir, android_project_root], "Android project error")
+                       end
+
+                       # Copy the whole `android` folder
+                       var android_dir = path / "android"
+                       if android_dir.file_exists then
+                               android_dir = android_dir.realpath
+                               toolcontext.exec_and_check(["cp", "-r", android_dir, root_compile_dir], "Android project error")
+                       end
+               end
+
+               # Is there an icon?
                var resolutions = ["ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"]
                var icon_available = false
                for res in resolutions do
@@ -270,40 +298,6 @@ $(call import-module,android/native_app_glue)
 
                toolcontext.exec_and_check(["ln", "-s", "{share_dir}/libgc/arm/include/gc/",
                        "{compile_dir}/gc"], "Android project error")
-
-               # Copy assets, resources and libs where expected by the SDK
-
-               # Link to assets (for mnit and others)
-               var assets_dir = project_root / "assets"
-               if assets_dir.file_exists then
-                       assets_dir = assets_dir.realpath
-                       var target_assets_dir = "{android_project_root}/assets"
-                       if not target_assets_dir.file_exists then
-                               toolcontext.exec_and_check(["ln", "-s", assets_dir, target_assets_dir], "Android project error")
-                       end
-               end
-
-               # Copy the res folder
-               var res_dir = project_root / "android/res"
-               if res_dir.file_exists then
-                       # copy the res folder to the compile dir
-                       res_dir = res_dir.realpath
-                       toolcontext.exec_and_check(["cp", "-R", res_dir, android_project_root], "Android project error")
-               end
-
-               if not res_dir.file_exists or not "{res_dir}/values/strings.xml".file_exists then
-                       # Create our own custom `res/values/string.xml` with the App name
-"""<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="app_name">{{{app_name}}}</string>
-</resources>""".write_to_file "{android_project_root}/res/values/strings.xml"
-               end
-
-               # Copy the libs folder
-               var libs_dir = project_root / "android/libs"
-               if libs_dir.file_exists then
-                       toolcontext.exec_and_check(["cp", "-r", libs_dir, android_project_root], "Android project error")
-               end
        end
 
        redef fun write_makefile(compile_dir, cfiles)
index 1d60f15..9cfdec9 100644 (file)
@@ -44,6 +44,9 @@ class AppProject
                return local_time_s.to_i
        end
 
+       # Extra folders where to find platform specific resource files
+       var files = new Array[String]
+
        private var modelbuilder: ModelBuilder
        private var mainmodule: MModule
 
@@ -64,6 +67,9 @@ class AppProject
                        if val != null then namespace = val
                end
 
+               var annots = modelbuilder.collect_annotations_on_modules("app_files", mainmodule)
+               for a in annots do files.add_all a.as_relative_paths(modelbuilder)
+
                modelbuilder.toolcontext.check_errors
        end
 
@@ -134,4 +140,29 @@ redef class AAnnotation
 
                return version_fields.join(".")
        end
+
+       # Parse all arguments as paths relative to the declaring module
+       #
+       # If no arguments are given, then use the parent directory of the module.
+       private fun as_relative_paths(modelbuilder: ModelBuilder): Array[String]
+       do
+               var paths = new Array[String]
+
+               var file = location.file
+               if file == null then return paths
+
+               var args = n_args
+               if args.is_empty then
+                       paths.add file.filename.dirname
+               else
+                       for arg in args do
+                               var val = arg.as_string
+                               if val != null then
+                                       paths.add file.filename.dirname/val
+                               else modelbuilder.error(arg, "Syntax Error: `app_files` expects String literals as arguments.")
+                       end
+               end
+
+               return paths
+       end
 end
index c221598..76fefea 100644 (file)
@@ -95,15 +95,22 @@ private class IOSToolchain
                        end
                end
 
-               var icon_dir = project_root / "ios" / "AppIcon.appiconset"
-               var icons_found = icon_dir.file_exists
-               if icons_found then
+               # 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
+               for path in app_files do
+                       var icon_dir = path / "ios" / "AppIcon.appiconset"
+                       if icon_dir.file_exists then
+                               icons_found = true
 
-                       """
+                               # 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,
@@ -111,9 +118,10 @@ private class IOSToolchain
   }
 }""".write_to_file target_assets_dir / "Contents.json"
 
-                       # 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")
+                               # 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
                end
 
                # TODO Register asset files