Top Level Namespace
- Extended by:
- Ruby2D::DSL
- Includes:
- Ruby2D
Defined Under Namespace
Modules: Ruby2D Classes: String
Constant Summary
Constants included from Ruby2D
Ruby2D::Colour, Ruby2D::VERSION
Instance Attribute Summary
Attributes included from Ruby2D
Instance Method Summary collapse
-
#add_flags(type, flags) ⇒ Object
Add compiler and linker flags.
-
#add_ld_flags(ld_flags, name, type, dir = nil) ⇒ Object
Add linker flags.
-
#build(target, ruby2d_app) ⇒ Object
Build the user’s application.
-
#build_ios_tvos(rb_file, device) ⇒ Object
Build an iOS or tvOS app.
-
#check_sdl ⇒ Object
Check for SDL libraries.
-
#clean_up(cmd = nil) ⇒ Object
Clean up unneeded build files.
-
#compile_native ⇒ Object
Create a native executable using the available C compiler.
-
#compile_web ⇒ Object
Create a WebAssembly executable using Emscripten.
-
#create_macos_bundle ⇒ Object
Build an app bundle for macOS.
- #doctor_native ⇒ Object
-
#doctor_web(mode = nil) ⇒ Object
Check for problems with web build.
-
#launch_apple(device) ⇒ Object
Launch an iOS or tvOS app in a simulator.
-
#launch_native ⇒ Object
Launch a native app.
-
#launch_web ⇒ Object
Launch a web app.
-
#print_errors ⇒ Object
Print installation errors.
-
#run_cmd(cmd) ⇒ Object
Helpers ######################################################################.
-
#set_linux_bsd_flags ⇒ Object
Set flags for Linux and BSD.
-
#set_rpi_flags ⇒ Object
Set Raspberry Pi flags.
-
#strip_require(file) ⇒ Object
Remove ‘require ’ruby2d’‘ from source file.
-
#use_usr_libs ⇒ Object
Use SDL and other libraries installed by the user (not those bundled with the gem).
Methods included from Ruby2D::DSL
clear, close, get, off, on, render, set, show, update, window, window=
Methods included from Ruby2D
Instance Method Details
#add_flags(type, flags) ⇒ Object
Add compiler and linker flags
19 20 21 22 23 24 25 26 |
# File 'ext/ruby2d/extconf.rb', line 19 def add_flags(type, flags) case type when :c $CFLAGS << " #{flags} " when :ld $LDFLAGS << " #{flags} " end end |
#add_ld_flags(ld_flags, name, type, dir = nil) ⇒ Object
Add linker flags
59 60 61 62 63 64 65 66 |
# File 'lib/ruby2d/cli/build.rb', line 59 def add_ld_flags(ld_flags, name, type, dir = nil) case type when :archive ld_flags << "#{dir}/lib#{name}.a " when :framework ld_flags << "-Wl,-framework,#{name} " end end |
#build(target, ruby2d_app) ⇒ Object
Build the user’s application
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/ruby2d/cli/build.rb', line 72 def build(target, ruby2d_app) # Check if source file provided is good if !ruby2d_app puts "Please provide a Ruby file to build" exit elsif !File.exist? ruby2d_app puts "Can't find file: #{ruby2d_app}" exit end # Add debugging information to produce backtrace if @debug then debug_flag = '-g' end # Create build directory FileUtils.mkdir_p 'build' # Assemble Ruby 2D library files into one '.rb' file ruby2d_lib_dir = "#{Ruby2D.gem_dir}/lib/ruby2d/" ruby2d_lib = '' @ruby2d_lib_files.each do |f| ruby2d_lib << File.read("#{ruby2d_lib_dir + f}.rb") + "\n\n" end File.write('build/ruby2d_lib.rb', ruby2d_lib) # Assemble the Ruby 2D C extension files into one '.c' file ruby2d_ext_dir = "#{Ruby2D.gem_dir}/ext/ruby2d/" ruby2d_ext = "#define MRUBY 1" << "\n\n" Dir["#{ruby2d_ext_dir}*.c"].each do |c_file| ruby2d_ext << File.read(c_file) end File.write('build/ruby2d_ext.c', ruby2d_ext) # Select `mrbc` executable based on platform case $RUBY2D_PLATFORM when :macos mrbc = "#{Ruby2D.assets}/macos/universal/bin/mrbc" when :windows mrbc = "#{Ruby2D.assets}/windows/mingw-w64-x86_64/bin/mrbc.exe" else mrbc = 'mrbc' end # Compile the Ruby 2D lib (`.rb` files) to mruby bytecode run_cmd "#{mrbc} #{debug_flag} -Bruby2d_lib -obuild/ruby2d_lib.c build/ruby2d_lib.rb" # Read the user's provided Ruby source file, copy to build dir and compile to bytecode File.open('build/ruby2d_app.rb', 'w') { |f| f << strip_require(ruby2d_app) } run_cmd "#{mrbc} #{debug_flag} -Bruby2d_app -obuild/ruby2d_app.c build/ruby2d_app.rb" # Combine contents of C source files and bytecode into one file open('build/app.c', 'w') do |f| ['ruby2d_app', 'ruby2d_lib', 'ruby2d_ext'].each do |c_file| f << File.read("build/#{c_file}.c") << "\n\n" end end # Compile the final application based on the target platform case target when :native compile_native when :web compile_web end # Remove files used in the build process clean_up unless @debug end |
#build_ios_tvos(rb_file, device) ⇒ Object
Build an iOS or tvOS app
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
# File 'lib/ruby2d/cli/build.rb', line 350 def build_ios_tvos(rb_file, device) check_build_src_file(rb_file) # Check if MRuby exists; if not, quit if `which mruby`.empty? puts "#{'Error:'.error} Can't find MRuby, which is needed to build native Ruby 2D applications.\n" exit end # Add debugging information to produce backtrace if @debug then debug_flag = '-g' end # Assemble the Ruby 2D library in one `.rb` file and compile to bytecode make_lib `mrbc #{debug_flag} -Bruby2d_lib -obuild/lib.c build/lib.rb` # Read the provided Ruby source file, copy to build dir and compile to bytecode File.open('build/src.rb', 'w') { |file| file << strip_require(rb_file) } `mrbc #{debug_flag} -Bruby2d_app -obuild/src.c build/src.rb` # Copy over iOS project FileUtils.cp_r "#{@gem_dir}/assets/#{device}", "build" # Combine contents of C source files and bytecode into one file File.open("build/#{device}/main.c", 'w') do |f| f << "#define RUBY2D_IOS_TVOS 1" << "\n\n" f << "#define MRUBY 1" << "\n\n" f << File.read("build/lib.c") << "\n\n" f << File.read("build/src.c") << "\n\n" f << File.read("#{@gem_dir}/ext/ruby2d/ruby2d.c") end # TODO: Need add this functionality to the gem # Build the Xcode project `simple2d build --#{device} build/#{device}/MyApp.xcodeproj` # Clean up clean_up unless @debug # Success! puts "App created: `build/#{device}`" end |
#check_sdl ⇒ Object
Check for SDL libraries
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'ext/ruby2d/extconf.rb', line 30 def check_sdl unless have_library('SDL2') && have_library('SDL2_image') && have_library('SDL2_mixer') && have_library('SDL2_ttf') $errors << "Couldn't find packages needed by Ruby 2D." case $platform when :linux, :linux_rpi # Fedora and CentOS if system('which yum') $errors << "Install the following packages using `yum` (or `dnf`) and try again:\n" << " SDL2-devel SDL2_image-devel SDL2_mixer-devel SDL2_ttf-devel".bold # Arch elsif system('which pacman') $errors << "Install the following packages using `pacman` and try again:\n" << " sdl2 sdl2_image sdl2_mixer sdl2_ttf".bold # openSUSE elsif system('which zypper') $errors << "Install the following packages using `zypper` and try again:\n" << " libSDL2-devel libSDL2_image-devel libSDL2_mixer-devel libSDL2_ttf-devel".bold # Ubuntu, Debian, and Mint # `apt` must be last because openSUSE has it aliased to `zypper` elsif system('which apt') $errors << "Install the following packages using `apt` and try again:\n" << " libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev".bold end when :bsd $errors << "Install the following packages using `pkg` and try again:\n" << " sdl2 sdl2_image sdl2_mixer sdl2_ttf".bold end $errors << "" << "See #{"ruby2d.com".bold} for additional help." print_errors; exit end end |
#clean_up(cmd = nil) ⇒ Object
Clean up unneeded build files
395 396 397 398 399 400 401 402 403 404 405 406 407 408 |
# File 'lib/ruby2d/cli/build.rb', line 395 def clean_up(cmd = nil) FileUtils.rm( Dir.glob('build/*.{rb,c,js}') ) if cmd == :all puts "cleaning up..." FileUtils.rm_f 'build/app' FileUtils.rm_f 'build/app.js' FileUtils.rm_f 'build/app.html' FileUtils.rm_rf 'build/App.app' FileUtils.rm_rf 'build/ios' FileUtils.rm_rf 'build/tvos' end end |
#compile_native ⇒ Object
Create a native executable using the available C compiler
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/ruby2d/cli/build.rb', line 150 def compile_native # Get include directories incl_dir_ruby2d = "#{Ruby2D.gem_dir}/ext/ruby2d/" incl_dir_deps = "#{Ruby2D.assets}/include/" # Add compiler flags for each platform case $RUBY2D_PLATFORM when :macos ld_dir = "#{Ruby2D.assets}/macos/universal/lib" c_flags = '-arch arm64 -arch x86_64' ld_flags = '' ['mruby', 'SDL2', 'SDL2_image', 'SDL2_mixer', 'SDL2_ttf', 'jpeg', 'jxl', 'avif', 'png', 'tiff', 'webp', 'mpg123', 'ogg', 'FLAC', 'vorbis', 'vorbisfile', 'modplug', 'freetype', 'harfbuzz', 'graphite2'].each do |name| add_ld_flags(ld_flags, name, :archive, ld_dir) end ld_flags << "-lz -lbz2 -liconv -lstdc++ " ['Cocoa', 'Carbon', 'CoreVideo', 'OpenGL', 'Metal', 'CoreAudio', 'AudioToolbox', 'IOKit', 'GameController', 'ForceFeedback', 'CoreHaptics'].each do |name| add_ld_flags(ld_flags, name, :framework) end when :linux, :linux_rpi, :bsd # TODO: implement this # ld_flags = '-lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lm -lGL' when :windows if RUBY_PLATFORM =~ /ucrt/ ld_dir = "#{Ruby2D.assets}/windows/mingw-w64-ucrt-x86_64/lib" else ld_dir = "#{Ruby2D.assets}/windows/mingw-w64-x86_64/lib" end ld_flags = '-static -Wl,--start-group ' ['mruby', 'SDL2', 'SDL2_image', 'jpeg', 'png', 'tiff', 'webp', 'jxl', 'hwy', 'jbig', 'deflate', 'lzma', 'zstd', 'Lerc', 'SDL2_mixer', 'mpg123', 'FLAC', 'vorbis', 'vorbisfile', 'ogg', 'modplug', 'opus', 'opusfile', 'sndfile', 'SDL2_ttf', 'freetype', 'harfbuzz', 'graphite2', 'bz2', 'brotlicommon', 'brotlidec', 'glew32', 'stdc++', 'z', 'ssp' ].each do |name| add_ld_flags(ld_flags, name, :archive, ld_dir) end ld_flags << '-lmingw32 -lopengl32 -lole32 -loleaut32 -limm32 -lversion -lwinmm -lrpcrt4 -mwindows -lsetupapi -ldwrite '\ '-lws2_32 -lshlwapi ' ld_flags << '-Wl,--end-group' end # Compile the app run_cmd "cc #{c_flags} -I#{incl_dir_ruby2d} -I#{incl_dir_deps} build/app.c #{ld_flags} -o build/app" create_macos_bundle if $RUBY2D_PLATFORM == :macos end |
#compile_web ⇒ Object
Create a WebAssembly executable using Emscripten
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
# File 'lib/ruby2d/cli/build.rb', line 213 def compile_web # Check for compiler toolchain issues if doctor_web(:building) puts "Fix errors before building.\n\n" end wasm_assets = "#{Ruby2D.assets}/wasm" # Get include directories incl_dir_ruby2d = "#{Ruby2D.gem_dir}/ext/ruby2d/" incl_dir_deps = "#{Ruby2D.assets}/include/" optimize_flags = '-Os --closure 1' ld_flags = "#{wasm_assets}/libmruby.a" # Compile using Emscripten run_cmd "emcc -s WASM=1 -I#{incl_dir_ruby2d} -I#{incl_dir_deps} "\ "-s USE_SDL=2 -s USE_SDL_IMAGE=2 -s USE_SDL_MIXER=2 -s USE_SDL_TTF=2 "\ "build/app.c #{ld_flags} -o build/app.html" # TODO: Copy HTML template from gem assets to build directory # FileUtils.cp "#{wasm_assets}/template.html", 'build/app.html' exit(1) unless $?.success? end |
#create_macos_bundle ⇒ Object
Build an app bundle for macOS
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
# File 'lib/ruby2d/cli/build.rb', line 307 def create_macos_bundle # Property list source for the bundle info_plist = %( <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleExecutable</key> <string>app</string> <key>CFBundleIconFile</key> <string>app.icns</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleVersion</key> <string>1</string> <key>NSHighResolutionCapable</key> <string>True</string> </dict> </plist> ) # Create directories FileUtils.mkpath 'build/App.app/Contents/MacOS' FileUtils.mkpath 'build/App.app/Contents/Resources' # Create Info.plist and copy over assets File.open('build/App.app/Contents/Info.plist', 'w') { |f| f.write(info_plist) } FileUtils.cp 'build/app', 'build/App.app/Contents/MacOS/' # Consider using an icon: # FileUtils.cp "#{@gem_dir}/assets/app.icns", 'build/App.app/Contents/Resources' # Clean up # FileUtils.rm_f 'build/app' unless @debug # Success! # puts 'macOS app bundle created: `build/App.app`' end |
#doctor_native ⇒ Object
241 242 243 244 245 246 247 |
# File 'lib/ruby2d/cli/build.rb', line 241 def doctor_native # Check if MRuby exists; if not, quit if `which mruby`.empty? puts "#{'Error:'.error} Can't find `mruby`, which is needed to build native Ruby 2D applications.\n" exit end end |
#doctor_web(mode = nil) ⇒ Object
Check for problems with web build
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 |
# File 'lib/ruby2d/cli/build.rb', line 251 def doctor_web(mode = nil) errors = false mruby_errors = false emscripten_errors = false puts "\nChecking for mruby" # Check for `mrbc` print ' mrbc...' if `which mrbc`.empty? puts 'not found'.error mruby_errors = true else puts 'found'.success end puts "\nChecking for Emscripten tools" # Check for `emcc` print ' emcc...' if `which emcc`.empty? puts 'not found'.error emscripten_errors = true else puts 'found'.success end # Check for `emar` print ' emar...' if `which emar`.empty? puts 'not found'.error emscripten_errors = true else puts 'found'.success end if mruby_errors || emscripten_errors then errors = true end if errors puts "\nErrors were found!\n\n" if mruby_errors puts "* Did you install mruby?" end if emscripten_errors puts "* Did you run \`./emsdk_env.sh\` ?", " For help, check out the \"Getting Started\" guide on webassembly.org" end puts "\n" exit(1) else puts "\n👍 Everything looks good!\n\n" end end |
#launch_apple(device) ⇒ Object
Launch an iOS or tvOS app in a simulator
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/ruby2d/cli/launch.rb', line 31 def launch_apple(device) case device when 'ios' if !File.exist? 'build/ios/build/Release-iphonesimulator/MyApp.app' puts "No iOS app built!" exit end puts `simple2d simulator --open "iPhone X" && simple2d simulator --install "build/ios/build/Release-iphonesimulator/MyApp.app" && simple2d simulator --launch "Ruby2D.MyApp"` when 'tvos' if !File.exist? 'build/tvos/build/Release-appletvsimulator/MyApp.app' puts "No tvOS app built!" exit end puts `simple2d simulator --open "Apple TV 4K" && simple2d simulator --install "build/tvos/build/Release-appletvsimulator/MyApp.app" && simple2d simulator --launch "Ruby2D.MyApp"` end end |
#launch_native ⇒ Object
Launch a native app
4 5 6 7 8 9 10 |
# File 'lib/ruby2d/cli/launch.rb', line 4 def launch_native if !File.exist? 'build/app' puts "No native app built!" exit end `( cd build && ./app )` end |
#launch_web ⇒ Object
Launch a web app
14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/ruby2d/cli/launch.rb', line 14 def launch_web if !File.exist? 'build/app.html' puts "No web app built!" exit end open_cmd = 'open' case RUBY_PLATFORM when /linux/ open_cmd = "xdg-#{open_cmd}" when /mingw/ open_cmd = "start" end system "#{open_cmd} build/app.html" end |
#print_errors ⇒ Object
Print installation errors
10 11 12 13 14 15 |
# File 'ext/ruby2d/extconf.rb', line 10 def print_errors puts " #{"== #{"Ruby 2D Installation Errors".error} =======================================\n"} #{$errors.join("\n ")}\n #{"======================================================================"}" end |
#run_cmd(cmd) ⇒ Object
Helpers ######################################################################
42 43 44 45 |
# File 'lib/ruby2d/cli/build.rb', line 42 def run_cmd(cmd) puts "#{'$'.info} #{cmd.bold}\n" if @debug system cmd end |
#set_linux_bsd_flags ⇒ Object
Set flags for Linux and BSD
79 80 81 82 83 84 |
# File 'ext/ruby2d/extconf.rb', line 79 def set_linux_bsd_flags check_sdl set_rpi_flags add_flags(:ld, "-lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lm") if $RUBY2D_PLATFORM == :linux then add_flags(:ld, '-lGL') end end |
#set_rpi_flags ⇒ Object
Set Raspberry Pi flags
70 71 72 73 74 75 |
# File 'ext/ruby2d/extconf.rb', line 70 def set_rpi_flags if $platform == :linux_rpi add_flags(:c, '-I/opt/vc/include') add_flags(:ld, '-L/opt/vc/lib -lbrcmGLESv2') end end |
#strip_require(file) ⇒ Object
Remove ‘require ’ruby2d’‘ from source file
49 50 51 52 53 54 55 |
# File 'lib/ruby2d/cli/build.rb', line 49 def strip_require(file) output = '' File.foreach(file) do |line| output << line unless line =~ /require ('|")ruby2d('|")/ end return output end |
#use_usr_libs ⇒ Object
Use SDL and other libraries installed by the user (not those bundled with the gem)
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'ext/ruby2d/extconf.rb', line 88 def use_usr_libs case $RUBY2D_PLATFORM when :macos add_flags(:c, `sdl2-config --cflags`) add_flags(:c, '-I/opt/homebrew/include') add_flags(:ld, `sdl2-config --libs`) add_flags(:ld, '-lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf') add_flags(:ld, '-Wl,-framework,OpenGL') when :windows add_flags(:ld, '-lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf') add_flags(:ld, '-lopengl32 -lglew32') when :linux_rpi set_linux_bsd_flags end end |