├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md └── Rakefile /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | tmp 3 | ios_build_config.rb 4 | MRuby.framework 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "mruby"] 2 | path = mruby 3 | url = https://github.com/mruby/mruby.git 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Carson McDonald 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 4 | associated documentation files (the "Software"), to deal in the Software without restriction, including 5 | without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 6 | copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the 7 | following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial 10 | portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 13 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO 14 | EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 15 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 16 | THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | This is a project that will build the current mruby source into a XCode 4 | framework. That framework can then be used to embed Ruby into an iOS 5 | application. 6 | 7 | For a complete example of using the product of the build check out 8 | [MRubyiOSExample](https://github.com/carsonmcdonald/MRubyiOSExample) 9 | 10 | This is not an attempt to make a bridge between Objective-C and Ruby, if you 11 | want that then check out the [mobiruby](http://mobiruby.org/) project. 12 | 13 | ## Build 14 | 15 | * git clone git://github.com/carsonmcdonald/ios-ruby-embedded.git 16 | * cd ios-ruby-embedded 17 | * git submodule init 18 | * git submodule update 19 | * rake 20 | 21 | After the above steps you should have a complete MRuby.framework framework 22 | structure that is ready to use. 23 | 24 | ## Install 25 | 26 | To install the framework in an XCode project follow these steps (these steps 27 | assume XCode 5.0.x): 28 | 29 | * Select the top of the project on the left hand project display 30 | * Select the "Build Phases" tab in the project details 31 | * Click the + button under the "Link Binary With Libraries" dropdown 32 | * Select "Add Other..." from the framework add popup 33 | * Navigate to the MRuby.framework direcotry in the file browser and click 34 | "Open" 35 | 36 | ## Example Use 37 | 38 | Assume you have the following simple Ruby script you want to execute: 39 | 40 | ``` 41 | puts "Hello world" 42 | ``` 43 | 44 | First you need to compile the script into byte code using the mrbc command 45 | that can be found in the bin directory after you have compiled the project: 46 | 47 | ``` 48 | mrbc helloworld.rb 49 | ``` 50 | 51 | The output of that command is a bytecode file that can be run using the mruby 52 | command found in the same bin directory. NB you currently need to cat all your 53 | script files together before compiling the, using require doesn't work. 54 | 55 | Once you have compiled your Ruby code and added it to your application bundle 56 | you can embed it in your app using something like the following code: 57 | 58 | ``` 59 | #include "mruby/mruby.h" 60 | #include "mruby/mruby/proc.h" 61 | #include "mruby/mruby/dump.h" 62 | 63 | // ... 64 | 65 | NSString *bcfile = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"helloworld.mrb"]; 66 | 67 | mrb_state *mrb = mrb_open(); 68 | FILE *fp = fopen([bcfile UTF8String], "rb"); 69 | if (fp == NULL) { 70 | NSLog(@"Error loading file..."); 71 | } else { 72 | int n = mrb_read_irep_file(mrb, fp); 73 | fclose(fp); 74 | 75 | mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb)); 76 | } 77 | ``` 78 | 79 | ## Notes 80 | 81 | * mruby is new and changing constantly, don't be surprised if this project 82 | doesn't build. 83 | * Currently you can't use the mruby compiler while embedded in an arm7 device. 84 | That is why you need to pre-compile the code using mrbc. It will work on the 85 | simulator but don't let that fool you into thinking it will work on a device. 86 | An app created to compile code would almost certainly have other issues. 87 | 88 | ## License 89 | 90 | MIT to match the mruby license. See the LICENSE file for full license. 91 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | XCODEROOT = %x[xcode-select -print-path].strip 2 | SIMSDKPATH = Dir["#{XCODEROOT}/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator*.sdk/"].sort.last 3 | IOSSDKPATH = Dir["#{XCODEROOT}/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.sdk/"].sort.last 4 | 5 | task :verify_sysroot => [SIMSDKPATH, IOSSDKPATH] 6 | 7 | file "ios_build_config.rb" do 8 | 9 | open('custom.gembox', 'w') do |gembox_file| 10 | gembox_file.puts <<__EOF__ 11 | MRuby::GemBox.new do |conf| 12 | # Use standard Kernel#sprintf method 13 | conf.gem :core => "mruby-sprintf" 14 | 15 | # Use standard print/puts/p 16 | conf.gem :core => "mruby-print" 17 | 18 | # Use standard Math module 19 | conf.gem :core => "mruby-math" 20 | 21 | # Use standard Time class 22 | conf.gem :core => "mruby-time" 23 | 24 | # Use standard Struct class 25 | conf.gem :core => "mruby-struct" 26 | 27 | # Use extensional Enumerable module 28 | conf.gem :core => "mruby-enum-ext" 29 | 30 | # Use extensional String class 31 | conf.gem :core => "mruby-string-ext" 32 | 33 | # Use extensional Numeric class 34 | conf.gem :core => "mruby-numeric-ext" 35 | 36 | # Use extensional Array class 37 | conf.gem :core => "mruby-array-ext" 38 | 39 | # Use extensional Hash class 40 | conf.gem :core => "mruby-hash-ext" 41 | 42 | # Use extensional Range class 43 | conf.gem :core => "mruby-range-ext" 44 | 45 | # Use extensional Proc class 46 | conf.gem :core => "mruby-proc-ext" 47 | 48 | # Use extensional Symbol class 49 | conf.gem :core => "mruby-symbol-ext" 50 | 51 | # Use Random class 52 | conf.gem :core => "mruby-random" 53 | 54 | # Use extensional Object class 55 | conf.gem :core => "mruby-object-ext" 56 | 57 | # Use ObjectSpace class 58 | conf.gem :core => "mruby-objectspace" 59 | 60 | # Use Fiber class 61 | conf.gem :core => "mruby-fiber" 62 | 63 | # Use Enumerator class (require mruby-fiber) 64 | conf.gem :core => "mruby-enumerator" 65 | 66 | # Use Enumerable::Lazy class (require mruby-enumerator) 67 | conf.gem :core => "mruby-enum-lazy" 68 | 69 | # Use extended toplevel object (main) methods 70 | conf.gem :core => "mruby-toplevel-ext" 71 | 72 | # Use extensional Kernel module 73 | conf.gem :core => "mruby-kernel-ext" 74 | end 75 | __EOF__ 76 | end 77 | 78 | FileUtils.cp "custom.gembox", "mruby/mrbgems/" 79 | 80 | open('ios_build_config.rb', 'w') do |config_file| 81 | 82 | config_file.puts <<__EOF__ 83 | MRuby::Build.new do |conf| 84 | toolchain :clang 85 | 86 | conf.gembox 'default' 87 | end 88 | 89 | SIM_SYSROOT="#{SIMSDKPATH}" 90 | DEVICE_SYSROOT="#{IOSSDKPATH}" 91 | 92 | MRuby::CrossBuild.new('ios-simulator') do |conf| 93 | conf.bins = [] 94 | 95 | conf.gembox 'custom' 96 | 97 | conf.cc do |cc| 98 | cc.command = 'xcrun' 99 | cc.flags = %W(-sdk iphoneos clang -miphoneos-version-min=5.0 -arch i386 -isysroot \#{SIM_SYSROOT} -g -O3 -Wall -Werror-implicit-function-declaration) 100 | end 101 | 102 | conf.linker do |linker| 103 | linker.command = 'xcrun' 104 | linker.flags = %W(-sdk iphoneos clang -miphoneos-version-min=5.0 -arch i386 -isysroot \#{SIM_SYSROOT}) 105 | end 106 | end 107 | 108 | MRuby::CrossBuild.new('ios-simulator-x86_64') do |conf| 109 | conf.bins = [] 110 | 111 | conf.gembox 'custom' 112 | 113 | conf.cc do |cc| 114 | cc.command = 'xcrun' 115 | cc.flags = %W(-sdk iphoneos clang -miphoneos-version-min=5.0 -arch x86_64 -isysroot \#{SIM_SYSROOT} -g -O3 -Wall -Werror-implicit-function-declaration) 116 | end 117 | 118 | conf.linker do |linker| 119 | linker.command = 'xcrun' 120 | linker.flags = %W(-sdk iphoneos clang -miphoneos-version-min=5.0 -arch x86_64 -isysroot \#{SIM_SYSROOT}) 121 | end 122 | end 123 | 124 | MRuby::CrossBuild.new('ios-armv7') do |conf| 125 | conf.bins = [] 126 | 127 | conf.gembox 'custom' 128 | 129 | conf.cc do |cc| 130 | cc.command = 'xcrun' 131 | cc.flags = %W(-sdk iphoneos clang -arch armv7 -isysroot \#{DEVICE_SYSROOT} -g -O3 -Wall -Werror-implicit-function-declaration) 132 | end 133 | 134 | conf.linker do |linker| 135 | linker.command = 'xcrun' 136 | linker.flags = %W(-sdk iphoneos clang -arch armv7 -isysroot \#{DEVICE_SYSROOT}) 137 | end 138 | end 139 | 140 | MRuby::CrossBuild.new('ios-armv7s') do |conf| 141 | conf.bins = [] 142 | 143 | conf.gembox 'custom' 144 | 145 | conf.cc do |cc| 146 | cc.command = 'xcrun' 147 | cc.flags = %W(-sdk iphoneos clang -arch armv7s -isysroot \#{DEVICE_SYSROOT} -g -O3 -Wall -Werror-implicit-function-declaration) 148 | end 149 | 150 | conf.linker do |linker| 151 | linker.command = 'xcrun' 152 | linker.flags = %W(-sdk iphoneos clang -arch armv7s -isysroot \#{DEVICE_SYSROOT}) 153 | end 154 | end 155 | 156 | MRuby::CrossBuild.new('ios-arm64') do |conf| 157 | conf.bins = [] 158 | 159 | conf.gembox 'custom' 160 | 161 | conf.cc do |cc| 162 | cc.command = 'xcrun' 163 | cc.flags = %W(-sdk iphoneos clang -arch arm64 -isysroot \#{DEVICE_SYSROOT} -g -O3 -Wall -Werror-implicit-function-declaration) 164 | end 165 | 166 | conf.linker do |linker| 167 | linker.command = 'xcrun' 168 | linker.flags = %W(-sdk iphoneos clang -arch arm64 -isysroot \#{DEVICE_SYSROOT}) 169 | end 170 | end 171 | __EOF__ 172 | 173 | end 174 | 175 | end 176 | 177 | directory "MRuby.framework/Versions" 178 | directory "MRuby.framework/Versions/1.0.0/" 179 | directory "MRuby.framework/Versions/1.0.0/Headers" 180 | directory "MRuby.framework/Versions/1.0.0/Resources" 181 | 182 | task "MRuby.framework/Versions/1.0.0/" => "MRuby.framework/Versions" do 183 | 184 | Dir.chdir("MRuby.framework/Versions/") do 185 | File.symlink("1.0.0", "Current") 186 | end 187 | Dir.chdir("MRuby.framework/") do 188 | File.symlink("Versions/Current/Headers", "Headers") 189 | File.symlink("Versions/Current/MRuby", "MRuby") 190 | File.symlink("Versions/Current/Resources", "Resources") 191 | end 192 | end 193 | 194 | task :build_mruby => "ios_build_config.rb" do 195 | Dir.chdir("mruby") do 196 | ENV['MRUBY_CONFIG'] = "../ios_build_config.rb" 197 | sh "rake" 198 | end 199 | end 200 | 201 | directory "bin" 202 | 203 | file "bin/mirb" => [:build_mruby, "bin"] do 204 | FileUtils.cp "mruby/build/host/bin/mirb", "bin/mirb" 205 | end 206 | 207 | file "bin/mrbc" => [:build_mruby, "bin"] do 208 | FileUtils.cp "mruby/build/host/bin/mrbc", "bin/mrbc" 209 | end 210 | 211 | file "bin/mruby" => [:build_mruby, "bin"] do 212 | FileUtils.cp "mruby/build/host/bin/mruby", "bin/mruby" 213 | end 214 | 215 | file "MRuby.framework/Versions/Current/MRuby" => [:build_mruby, "MRuby.framework/Versions/1.0.0/"] do 216 | sh "#{XCODEROOT}/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo -arch i386 mruby/build/ios-simulator/lib/libmruby.a -arch x86_64 mruby/build/ios-simulator-x86_64/lib/libmruby.a -arch arm64 mruby/build/ios-arm64/lib/libmruby.a -arch armv7 mruby/build/ios-armv7/lib/libmruby.a -arch armv7s mruby/build/ios-armv7s/lib/libmruby.a -create -output MRuby.framework/Versions/Current/MRuby" 217 | end 218 | 219 | task :mruby_headers => [:build_mruby, "MRuby.framework/Versions/1.0.0/Headers"] do 220 | FileUtils.cp_r "mruby/include/.", "MRuby.framework/Versions/Current/Headers/" 221 | 222 | sh "sed -i '' 's/mruby\\.h/..\\/mruby\\.h/g' MRuby.framework/Versions/Current/Headers/mruby/*" 223 | sh "sed -i '' 's/mruby\\/khash\\.h/..\\/mruby\\/khash\\.h/g' MRuby.framework/Versions/Current/Headers/mruby/*" 224 | sh "sed -i '' 's/mruby\\/irep\\.h/..\\/mruby\\/irep\\.h/g' MRuby.framework/Versions/Current/Headers/mruby/proc.h" 225 | sh "sed -i '' 's/mruby\\/irep\\.h/..\\/mruby\\/irep\\.h/g' MRuby.framework/Versions/Current/Headers/mruby/dump.h" 226 | sh "sed -i '' 's/mruby\\/object\\.h/..\\/mruby\\/object\\.h/g' MRuby.framework/Versions/Current/Headers/mruby/value.h" 227 | sh "sed -i '' 's/mruby\\/compile\\.h/..\\/mruby\\/compile\\.h/g' MRuby.framework/Versions/Current/Headers/mruby/irep.h" 228 | end 229 | 230 | task :all => [:verify_sysroot, "bin/mirb", "bin/mrbc", "bin/mruby", "MRuby.framework/Versions/Current/MRuby", :mruby_headers] 231 | 232 | task :default => :all 233 | 234 | task :clean => "ios_build_config.rb" do 235 | Dir.chdir("mruby") do 236 | ENV['MRUBY_CONFIG'] = "../ios_build_config.rb" 237 | sh "rake clean" 238 | end 239 | FileUtils.rm_f ["ios_build_config.rb", "bin/mirb", "bin/mrbc", "bin/mruby", "custom.gembox", "mruby/mrbgems/custom.gembox"] 240 | FileUtils.rm_rf "MRuby.framework" 241 | end 242 | --------------------------------------------------------------------------------