#!/usr/bin/env ruby $VERBOSE = nil # Don't care about world writable dir warnings and the like require 'pathname' require 'fileutils' class OrigenBootError < StandardError end ORIGEN_MIN_GCC_VERSION = '4.6.3' # Keep a note of the pwd at the time when Origen was first loaded, this is initially used # by the site_config lookup. $_origen_invocation_pwd ||= Pathname.pwd load File.expand_path('../../lib/origen/operating_systems.rb', __FILE__) load File.expand_path('../../lib/origen/site_config.rb', __FILE__) # This will be referenced later in ruby_version_check, the origen used to launch # the process is different than the one that actually runs under bundler $origen_launch_root = Pathname.new(File.dirname(__FILE__)).parent # Override any influence from $LANG in the users environment Encoding.default_external = Encoding::UTF_8 Encoding.default_internal = Encoding::UTF_8 ENV['LC_ALL'] = nil ENV['LANG'] = nil ENV['LANG'] = 'en_US.UTF-8' # Work out what Origen.root is if we are running inside an Origen application, this will be # later used to execute from that app's bundle even if the origen executable lives somewhere # else (e.g. in the tools repository) app_config = File.join('config', 'application.rb') if File.exist?(app_config) origen_root = Dir.pwd else path = Pathname.new(Dir.pwd) until path.root? || origen_root if File.exist?(File.join(path, app_config)) origen_root = path.to_s else path = path.parent end end end if origen_root # If it looks like a bundled binstub of origen exists, and we have not been invoked through that, # then run that instead. if Origen.site_config.gem_manage_bundler && File.exist?("#{origen_root}/lbin/origen") && !ENV['BUNDLE_BIN_PATH'] && File.exist?(File.expand_path(Origen.site_config.gem_install_dir)) exec Gem.ruby, "#{origen_root}/lbin/origen", *ARGV exit 0 else # Force everyone to have a consistent way of installing gems with bundler ENV['BUNDLE_GEMFILE'] = File.join(origen_root, 'Gemfile') ENV['BUNDLE_PATH'] = File.expand_path(Origen.site_config.gem_install_dir) ENV['BUNDLE_BIN'] = File.join(origen_root, 'lbin') end end if origen_root && File.exist?(ENV['BUNDLE_GEMFILE']) && Origen.site_config.gem_manage_bundler # Retrieve any system gem specs that might be required before we enter the clean env if Origen.site_config.gem_manage_bundler && Origen.site_config.gem_use_from_system system_gem_specs = Origen.site_config.gem_use_from_system.map do |gem, version| begin Gem::Specification.find_by_name(gem, version) rescue Gem::LoadError end end else system_gem_specs = [] end # Overriding bundler here so that bundle install can be automated as required require 'bundler/shared_helpers' if Bundler::SharedHelpers.in_bundle? require 'bundler' if STDOUT.tty? begin fail OrigenBootError unless File.exist?(ENV['BUNDLE_BIN']) Bundler.setup fail OrigenBootError unless File.exist?(ENV['BUNDLE_BIN']) rescue Gem::LoadError, Bundler::BundlerError, OrigenBootError => e cmd = "bundle install --gemfile #{ENV['BUNDLE_GEMFILE']} --binstubs #{ENV['BUNDLE_BIN']} --path #{ENV['BUNDLE_PATH']}" # puts cmd puts 'Installing required gems...' puts `chmod o-w #{origen_root}` # Stops some annoying world writable warnings during install `chmod o-w #{origen_root}/bin` if File.exist?("#{origen_root}/bin") `chmod o-w #{origen_root}/.bin` if File.exist?("#{origen_root}/.bin") result = false # Set this here since the clean environment will not have access to the ENV variable local_gem_dir = "#{ENV['BUNDLE_PATH']}/ruby/#{Pathname.new(Gem.dir).basename}" Bundler.with_clean_env do if Origen.os.unix? if Origen.site_config.gem_build_switches Origen.site_config.gem_build_switches.each do |switches| `bundle config build.#{switches}` end end gcc_version = begin begin line = `gcc --version`.split("\n").first rescue puts "You don't seem to have gcc available, make sure you following the Origen installation instructions:" puts 'http://origen-sdk.org/origen/latest/guides/starting/installing/' exit 1 end if line =~ /(\d+\.\d+\.\d+)/ Regexp.last_match(1) end end if gcc_version if gcc_version < ORIGEN_MIN_GCC_VERSION puts "Origen requires a minimum of GCC version #{ORIGEN_MIN_GCC_VERSION}, but you have #{gcc_version}." exit 1 end else puts 'Unable to determine gcc version, proceeding with fingers crossed...' end # Need to compact the system gem specs array to remove reference to any nil elements which will cause an error below. system_gem_specs.compact! # Some gems (particularly those with C extensions that need to be built), can be hard to install reliably # across a large user base. Initially seed the user's local gem area with the system-installed gems, # this means that the system Ruby owner can provide an installation for these hard-to-install gems. unless system_gem_specs.empty? %w(bin cache extensions gems specifications).each do |subdir| d = "#{local_gem_dir}/#{subdir}" FileUtils.mkdir_p(d) unless File.exist?(d) end system_gem_specs.each do |spec| begin (spec.executables || []).each do |bin| unless File.exist?("#{local_gem_dir}/bin/#{bin}") FileUtils.cp("#{spec.bin_dir}/#{bin}", "#{local_gem_dir}/bin") end end p = Pathname.new(spec.cache_file) unless File.exist?("#{local_gem_dir}/cache/#{p.basename}") FileUtils.cp(spec.cache_file, "#{local_gem_dir}/cache") end if spec.extension_dir && File.exist?(spec.extension_dir) spec.extension_dir =~ /.*extensions(.*)/ sub_dir = Pathname.new(Regexp.last_match(1)).dirname.to_s local_ext_dir = "#{local_gem_dir}/extensions/#{sub_dir}" FileUtils.mkdir_p(local_ext_dir) unless File.exist?(local_ext_dir) # If the file exists in the extensions directory, skip copying it over. p = Pathname.new(spec.extension_dir) unless File.exist?("#{local_ext_dir}/#{p.basename}") FileUtils.cp_r(spec.extension_dir, local_ext_dir) end end # If the file exists in the gem directory, skip copying it over. p = Pathname.new(spec.gem_dir) unless File.exist?("#{local_gem_dir}/gems/#{p.basename}") FileUtils.cp_r(spec.gem_dir, "#{local_gem_dir}/gems") end # If the file exists in the specifications directory, skip copying it over. p = Pathname.new(spec.spec_file) unless File.exist?("#{local_gem_dir}/specifications/#{p.basename}") FileUtils.cp(spec.spec_file, "#{local_gem_dir}/specifications") end rescue puts "Had problems installing #{spec.name} from your system Ruby, proceeding with fingers crossed..." end end end end result = system(cmd) end `chmod o-w #{ENV['BUNDLE_BIN']}` # Make .bat versions of all executables, Bundler should really be doing this when running # on windows if Origen.os.windows? bat_present = File.exist? "#{origen_root}/lbin/origen.bat" Dir.glob("#{origen_root}/lbin/*").each do |bin| unless bin =~ /.bat$/ bat = "#{bin}.bat" unless File.exist?(bat) File.open(bat, 'w') { |f| f.write('@"ruby.exe" "%~dpn0" %*') } end end end if !bat_present && !result puts 'Some Windows specific updates to your workspace were required, please re-run the last command' exit 0 end end if result # This is a shim to help NXP run regression tests between an old version of an app running # RGen and a new version running Origen origen = File.join(ENV['BUNDLE_BIN'], 'origen') rgen = File.join(ENV['BUNDLE_BIN'], 'rgen') if File.exist?(rgen) && !File.exist?(origen) && Origen.os.linux? exec "ln -s #{rgen} #{origen}" end exec "origen #{ARGV.join(' ')}" exit 0 else puts puts "If you have just updated a gem version and are now getting an error that Bundler cannot find compatible versions for it then first try running 'bundle update '." puts "For example if you have just changed the version of origen_core run 'bundle update origen_core'." exit 1 end end else Bundler.setup end end require 'bundler/setup' require 'origen' else $LOAD_PATH.unshift "#{File.expand_path(File.dirname(__FILE__))}/../lib" require 'origen' end # This is a shim to help NXP run regression tests between an old version of an app running # RGen and a new version running Origen # If RGen < 3 is present then abort the process here and execute the rgen bin file instead begin require 'rgen' if RGen.version.major == 2 exec Gem.ruby, "#{RGen.top}/bin/rgen", *ARGV exit 0 end rescue LoadError # No problem, RGen not present end begin # If this script has been invoked from within an Origen application then open # up all commands, if not then only allow the command to create a new Origen # application. if origen_root require 'origen/commands' else require 'origen/commands_global' end rescue Exception => e unless e.is_a?(SystemExit) && e.status == 0 puts if Origen.app_loaded? puts 'COMPLETE CALL STACK' puts '-------------------' puts e.message unless e.is_a?(SystemExit) puts e.backtrace puts puts 'APPLICATION CALL STACK' puts '----------------------' puts e.message unless e.is_a?(SystemExit) # Only print out the application stack trace by default, if verbose logging is # enabled then output the full thing e.backtrace.each do |line| path = Pathname.new(line) if path.absolute? if line =~ /^#{Origen.root}/ && line !~ /^#{Origen.root}\/lbin/ puts line end else puts line unless line =~ /^.\/lbin/ end end else puts 'COMPLETE CALL STACK' puts '-------------------' puts e.message unless e.is_a?(SystemExit) puts e.backtrace end exit 1 end ensure if Origen.app_loaded? Origen.app.listeners_for(:on_origen_shutdown).each(&:on_origen_shutdown) Origen.app.runner.shutdown end end