diff --git a/motion/project/template/android.rb b/motion/project/template/android.rb index b143961..594881d 100644 --- a/motion/project/template/android.rb +++ b/motion/project/template/android.rb @@ -204,7 +204,12 @@ end r_classes = Dir.glob(classes_dir + '/**/R\$*[a-z]*.class').sort.map { |c| "'#{c}'" } - sh "RUBYOPT='' \"#{App.config.bin_exec('android/gen_bridge_metadata')}\" #{r_classes.join(' ')} -o \"#{r_bs}\" " + cmd = "RUBYOPT='' \"#{App.config.bin_exec('android/gen_bridge_metadata')}\" #{r_classes.join(' ')} -o \"#{r_bs}\" " + if defined?(Bundler) + Bundler.respond_to?(:with_unbundled_env) ? Bundler.with_unbundled_env { sh(cmd) } : Bundler.with_original_env { sh(cmd) } + else + sh(cmd) + end classes_changed = true end @@ -363,7 +368,11 @@ # copy over libc++_shared.so to the build directory for apk bundling sh "cp \"#{App.config.ndk_path}/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so\" \"#{app_build_dir}/#{libs_abi_subpath}/libc++_shared.so\"" - sh "cp -R ./assets/ #{File.join app_build_dir, "obj", "assets/"}" + App.config.assets_dirs.each do |assets_dir| + if File.exist?(assets_dir) + sh "cp -R #{assets_dir}/ #{File.join app_build_dir, "obj", "assets/"}" + end + end libpayload_subpaths << "#{libs_abi_subpath}/libc++_shared.so" # Copy the gdb server. @@ -554,7 +563,7 @@ end compile_java_file = Proc.new do |classes_dir, java_path| App.info 'Create', java_path if Rake.application.options.trace - sh "/usr/bin/javac -d \"#{classes_dir}\" -classpath #{class_path} -sourcepath \"#{java_dir}\" -target 1.5 -bootclasspath \"#{android_jar}\" -encoding UTF-8 -g -source 1.5 \"#{java_path}\"" + sh "/usr/bin/javac -d \"#{classes_dir}\" -classpath #{class_path} -sourcepath \"#{java_dir}\" -target 1.6 -bootclasspath \"#{android_jar}\" -encoding UTF-8 -g -source 1.6 \"#{java_path}\"" classes_changed = true end parallel = Motion::Project::ParallelBuilder.new(classes_dir, compile_java_file) diff --git a/motion/project/template/cross-platform.rb b/motion/project/template/cross-platform.rb new file mode 100644 index 0000000..50651f8 --- /dev/null +++ b/motion/project/template/cross-platform.rb @@ -0,0 +1,326 @@ +if platform = ENV["platform"] + require "motion/project/template/#{platform}" + require "motion/project/template/cross-platform/config" + + def remove_files(dir_name) + Motion::Project::App.config.files.delete_if do |path| + path.is_a?(String) && path.start_with?(dir_name) + end + end + + case platform + when "android" + remove_files "./app/ios" + remove_files "./app/osx" + remove_files "./app/cocoa" + Motion::Project::App.setup do |app| + app.resources_dirs = [] + end + when "ios" + remove_files "./app/android" + remove_files "./app/osx" + when "osx" + when "osx" + remove_files "./app/android" + end +else + # This allows the app setup method to be called, even + # though we don't know which platform to use yet. + module Motion; module Project; class App + def self.setup; end # no-op + end; end; end + + def invoke_rake(platform, task) + trace = Rake.application.options.trace == true + system "platform=#{platform} rake \"#{task}\" #{trace ? "--trace" : ""}" or exit 1 + end + + namespace "ios" do + desc "Create an .ipa archive" + task "archive" do + invoke_rake "ios", "archive" + end + + desc "Create an .ipa archive for distribution (AppStore)" + task "archive:distribution" do + invoke_rake "ios", "archive:distribution" + end + + desc "Build everything" + task "build" do + invoke_rake "ios", "build" + end + + desc "Build the device version" + task "build:device" do + invoke_rake "ios", "build:device" + end + + desc "Build the simulator version" + task "build:simulator" do + invoke_rake "ios", "build:simulator" + end + + desc "Clear local build objects" + task "clean" do + invoke_rake "ios", "clean" + end + + desc "Clean all build objects" + task "clean:all" do + invoke_rake "ios", "clean:all" + end + + desc "Show project config" + task "config" do + invoke_rake "ios", "config" + end + + desc "Same as crashlog:simulator" + task "crashlog" do + invoke_rake "ios", "crashlog" + end + + desc "Retrieve and symbolicate crash logs generated by the app on the device, and open the latest generated one" + task "crashlog:device" do + invoke_rake "ios", "crashlog:device" + end + + desc "Open the latest crash report generated by the app in the simulator" + task "crashlog:simulator" do + invoke_rake "ios", "crashlog:simulator" + end + + desc "Generate ctags" + task "ctags" do + invoke_rake "ios", "ctags" + end + + desc "Build the project, then run the simulator" + task "default" do + invoke_rake "ios", "default" + end + + desc "Deploy on the device" + task "device" do + invoke_rake "ios", "device" + end + + desc "Same as profile:simulator" + task "profile" do + invoke_rake "ios", "profile" + end + + desc "Run a build on the device through Instruments" + task "profile:device" do + invoke_rake "ios", "profile:device" + end + + desc "List all built-in device Instruments templates" + task "profile:device:templates" do + invoke_rake "ios", "profile:device:templates" + end + + desc "Run a build on the simulator through Instruments" + task "profile:simulator" do + invoke_rake "ios", "profile:simulator" + end + + desc "List all built-in Simulator Instruments templates" + task "profile:simulator:templates" do + invoke_rake "ios", "profile:simulator:templates" + end + + desc "Run the simulator" + task "simulator" do + invoke_rake "ios", "simulator" + end + + desc "Same as spec:simulator" + task "spec" do + invoke_rake "ios", "spec" + end + + desc "Run the test/spec suite on the device" + task "spec:device" do + invoke_rake "ios", "spec:device" + end + + desc "Run the test/spec suite on the simulator" + task "spec:simulator" do + invoke_rake "ios", "spec:simulator" + end + + desc "Create a .a static library" + task "static" do + invoke_rake "ios", "static" + end + + desc "Same as watch:simulator" + task "watch" do + invoke_rake "ios", "watch" + end + + desc "Run the Watch application on the simulator" + task "watch:simulator" do + invoke_rake "ios", "watch:simulator" + end + end + + namespace "android" do + desc "Create an application package file (.apk)" + task "build" do + invoke_rake "android", "build" + end + + desc "Clear local build objects" + task "clean" do + invoke_rake "android", "clean" + end + + desc "Clean all build objects" + task "clean:all" do + invoke_rake "android", "clean:all" + end + + desc "Show project config" + task "config" do + invoke_rake "android", "config" + end + + desc "Generate ctags" + task "ctags" do + invoke_rake "android", "ctags" + end + + desc "Same as rake emulator" + task "default" do + invoke_rake "android", "default" + end + + desc "Build the app then run it in the device" + task "device" do + invoke_rake "android", "device" + end + + desc "Install the app in the device" + task "device:install" do + invoke_rake "android", "device:install" + end + + desc "Start the app's main intent in the device" + task "device:start" do + invoke_rake "android", "device:start" + end + + desc "Build the app then run it in the emulator" + task "emulator" do + invoke_rake "android", "emulator" + end + + desc "Install the app in the emulator" + task "emulator:install" do + invoke_rake "android", "emulator:install" + end + + desc "Start the app's main intent in the emulator" + task "emulator:start" do + invoke_rake "android", "emulator:start" + end + + desc "Create an application package file (.apk) for release (Google Play)" + task "release" do + invoke_rake "android", "release" + end + + desc "Same as spec:emulator" + task "spec" do + invoke_rake "android", "spec" + end + + desc "Run the test/spec suite on the device" + task "spec:device" do + invoke_rake "android", "spec:device" + end + + desc "Run the test/spec suite on the emulator" + task "spec:emulator" do + invoke_rake "android", "spec:emulator" + end + + desc "Download and build dependencies" + task "gradle:install" do + invoke_rake "android", "gradle:install" + end + end + + namespace "osx" do + desc "Build the project for development" + task "build" do + invoke_rake "osx", "build" + end + + desc "Build the project for release" + task "build:release" do + invoke_rake "osx", "build:release" + end + + desc "Run the project" + task "run" do + invoke_rake "osx", "run" + end + + desc "Run the test/spec suite" + task "spec" do + invoke_rake "osx", "spec" + end + + desc "Create a .pkg archive" + task "archive" do + invoke_rake "osx", "archive" + end + + desc "Create a .pkg archive for distribution (AppStore)" + task "archive:distribution" do + invoke_rake "osx", "archive:distribution" + end + + desc "Create a .a static library" + task "static" do + invoke_rake "osx", "static" + end + + desc "Open the latest crash report generated for the app" + task "crashlog" do + invoke_rake "osx", "crashlog" + end + + desc "Clear local build objects" + task "clean" do + invoke_rake "osx", "clean" + end + end + + desc "Start a combined iOS/Android REPL" + task "super_repl" do + require "readline" + + cmd = %w{ rake } + ios_cmd = cmd + ["ios:simulator"] + android_cmd = cmd + ["android:emulator:start"] + + if ENV.fetch("skip_build", nil) + ios_cmd << "skip_build=1" + android_cmd << "skip_build=1" + end + + ios_io = IO.popen(ios_cmd.join(" "), "w") + android_io = IO.popen(android_cmd.join(" "), "w") + + while expr = Readline.readline("> ", true) + ios_io.puts expr + android_io.puts expr + sleep 0.2 + end + end +end diff --git a/motion/project/template/cross-platform/config.rb b/motion/project/template/cross-platform/config.rb new file mode 100644 index 0000000..9393d52 --- /dev/null +++ b/motion/project/template/cross-platform/config.rb @@ -0,0 +1,12 @@ +module Motion + module Project + class Config + # Allows us to define the config in one file but only + # execute it when it matches the specified platform. + def platform(platform_name) + return unless platform_name.to_sym == template + yield + end + end + end +end diff --git a/motion/project/template/cross-platform/files/.gitignore b/motion/project/template/cross-platform/files/.gitignore new file mode 100644 index 0000000..a9b45d9 --- /dev/null +++ b/motion/project/template/cross-platform/files/.gitignore @@ -0,0 +1,4 @@ +.repl_history +build +tags +.DS_Store diff --git a/motion/project/template/cross-platform/files/Gemfile b/motion/project/template/cross-platform/files/Gemfile new file mode 100644 index 0000000..9880b5c --- /dev/null +++ b/motion/project/template/cross-platform/files/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "rake" diff --git a/motion/project/template/cross-platform/files/Rakefile.erb b/motion/project/template/cross-platform/files/Rakefile.erb new file mode 100644 index 0000000..251eae7 --- /dev/null +++ b/motion/project/template/cross-platform/files/Rakefile.erb @@ -0,0 +1,21 @@ +$:.unshift("/Library/RubyMotion/lib") +$:.unshift("~/.rubymotion/rubymotion-templates") +require "motion/project/template/cross-platform" + +require "bundler" +Bundler.require + +Motion::Project::App.setup do |app| + app.name = "<%= name %>" + + app.platform(:android) do + # Android-specific configuration + app.api_version = "30" + app.archs = ["armv7", "arm64-v8a"] + end + + app.platform(:ios) do + # iOS-specific configuration + app.deployment_target = "10.0" + end +end diff --git a/motion/project/template/cross-platform/files/app/android/main_activity.rb b/motion/project/template/cross-platform/files/app/android/main_activity.rb new file mode 100644 index 0000000..bb92b5c --- /dev/null +++ b/motion/project/template/cross-platform/files/app/android/main_activity.rb @@ -0,0 +1,5 @@ +class MainActivity < Android::App::Activity + def onCreate(savedInstanceState) + super + end +end diff --git a/motion/project/template/cross-platform/files/app/ios/app_delegate.rb.erb b/motion/project/template/cross-platform/files/app/ios/app_delegate.rb.erb new file mode 100644 index 0000000..a24f13e --- /dev/null +++ b/motion/project/template/cross-platform/files/app/ios/app_delegate.rb.erb @@ -0,0 +1,15 @@ +class AppDelegate + def application(application, didFinishLaunchingWithOptions:launchOptions) + rootViewController = UIViewController.alloc.init + rootViewController.title = '<%= name %>' + rootViewController.view.backgroundColor = UIColor.whiteColor + + navigationController = UINavigationController.alloc.initWithRootViewController(rootViewController) + + @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds) + @window.rootViewController = navigationController + @window.makeKeyAndVisible + + true + end +end diff --git a/motion/project/template/cross-platform/files/resources/Default-568h@2x.png b/motion/project/template/cross-platform/files/resources/Default-568h@2x.png new file mode 100644 index 0000000..c6a1442 Binary files /dev/null and b/motion/project/template/cross-platform/files/resources/Default-568h@2x.png differ diff --git a/motion/project/template/cross-platform/files/resources/Default-667h@2x.png b/motion/project/template/cross-platform/files/resources/Default-667h@2x.png new file mode 100644 index 0000000..3ebfde1 Binary files /dev/null and b/motion/project/template/cross-platform/files/resources/Default-667h@2x.png differ diff --git a/motion/project/template/cross-platform/files/resources/Default-736h@3x.png b/motion/project/template/cross-platform/files/resources/Default-736h@3x.png new file mode 100644 index 0000000..25605a3 Binary files /dev/null and b/motion/project/template/cross-platform/files/resources/Default-736h@3x.png differ