Added `zip()` & `unzip()` extensions to easily create / extract archives from build scripts.
Under Windows `zip() creates `.zip`, under Linux it creates `.tar.bz2`. As a side effect, `zip()`
automatically generates SHA256 checksum and stores it along the archive in in `.zip.sha256` or
`.tar.bz2.sha256`. The SHA256 checksum is automatically checked by `unzip()` if corresponding
`.sha256` file exists.
defined? BUILD_DIR or BUILD_DIR = 'build'
defined? BUILD_ID or BUILD_ID = ENV['BUILD_NUMBER'] ? "build#{ENV['BUILD_NUMBER']}" : "#{Time.now.strftime("%Y%m%d")}"
defined? ARTIFACTS_DIR or ARTIFACTS_DIR = 'artifacts'
defined? REPORT_DIR or REPORT_DIR = 'reports'
defined? DEBUG or DEBUG = nil
if win32?
ENV['CVS_RSH'] = 'plink' if not ENV['CVS_RSH']
ENV['BCB'] = 'C:\\Borland\\BCC55' if not ENV['BCB']
end
if File.exist? '.config.rake'
load '.config.rake'
end
defined? PROJECT or PROJECT = 'stx:jv-branch'
if not defined? ARCH then
if ENV.has_key? 'ARCH' then
ARCH = ENV['ARCH']
else
ARCH = RbConfig::CONFIG['host_cpu']
end
if ARCH != 'i386' && ARCH != 'x86_64' then
raise Exception.new("Unsupported architecture #{ARCH}")
end
end
if not defined? TOOLCHAIN then
if ENV.has_key? 'TOOLCHAIN' then
TOOLCHAIN = ENV['TOOLCHAIN']
else
if unix? then
TOOLCHAIN='gcc'
elsif win32? then
if ARCH == 'x86_64' then
TOOLCHAIN='mingw64'
else
# TOOLCHAIN='bcc'
TOOLCHAIN="mingw32"
end
else
raise new Exception("Unsupported operating system")
end
end
end
if File.exist? '.config.rake'
if defined? PROJECT
File.open('.config.rake', 'w') do | f |
f.puts "PROJECT='#{PROJECT}' if not defined? PROJECT"
f.puts "ARCH='#{ARCH}' if not defined? ARCH"
if defined? PROJECT_DIRS
f.puts "PROJECT_DIRS='#{PROJECT_DIRS}' if not defined? PROJECT_DIRS"
end
end
end
end
defined? PROJECT_DIRS or PROJECT_DIRS = ''
if TOOLCHAIN == 'gcc' then
OBJ_DIR = '.'
OBJ_SUFFIX = 'o'
MAKE='make'
elsif TOOLCHAIN == 'bcc' then
OBJ_DIR = 'objbc'
OBJ_SUFFIX = 'obj'
MAKE='bmake.bat -DUSEBC'
elsif TOOLCHAIN == 'mingw64' then
if not File.exist? 'C:\mingw64\bin' then
raise new Exception("MINGW64 not found in C:\\mingw64!")
end
ENV['MINGW_DIR'] ='C:\MINGW64'
ENV['MINGW'] = '__MINGW64__'
ENV['USEMINGW_ARG'] = '-DUSEMINGW64'
OBJ_DIR = 'objmingw'
OBJ_SUFFIX = 'obj'
MAKE='mingwmake.bat'
ENV["PATH"] = "#{ENV['PATH']};#{ENV['MINGW_DIR']}\\bin"
elsif (TOOLCHAIN == 'mingw' or TOOLCHAIN == 'mingw32') then
if not File.exist? 'C:\mingw\bin' then
raise new Exception("MINGW not found in C:\\mingw!")
end
ENV['MINGW_DIR'] ='C:\MINGW'
ENV['MINGW'] = '__MINGW32__'
ENV['USEMINGW_ARG'] = '-DUSEMINGW32'
OBJ_DIR = 'objmingw'
OBJ_SUFFIX = 'obj'
MAKE='mingwmake.bat'
ENV["PATH"] = "#{ENV['PATH']};#{ENV['MINGW_DIR']}\\bin"
else
raise new Exception("Unsupported toolchain: #{TOOLCHAIN}")
end
task :'setup' => [ :'setup:pre',
:'setup:main',
:'setup:post' ]
task :'setup:pre'
task :'setup:post'
task :'setup:main' => [ :'setup:projects', :'setup:project' , :'setup:tasks' ];
task :'setup:projects' do
Rake::Stx::Configuration.read_specs(PROJECT_DIRS)
end
task :'setup:project' => :'setup:projects' do
error("PROJECT variable not defined!") if not defined? PROJECT
project! PROJECT.to_sym
project.apply_imports()
app_name = project.app_name || 'smalltalkx'
app_version = project.app_version || '6.2.5'
defined? BUILD_NAME or BUILD_NAME = "#{app_name}-#{app_version}_#{ARCH}-#{win32? ? 'win32' : RbConfig::CONFIG['host_os']}"
end
task :'setup:tasks' => :'setup:tasks:internal'
task :'setup:tasks:internal' => :'setup:project' do
project().tasks.each do | t |
t.define!
end
# compute required packages - bit hacky!
pkgs_all = project.packages.collect { | p | p.name }
if project.application
pkgs_all += [ project.application.name ]
pkgs_reqd = Rake::Task[project.application.name].all_prerequisites_sorted
else
pkgs_reqd = (project.packages.select { | p | not p.link }).collect { | p | p.name }
end
pkgs_reqd = pkgs_reqd.reject { | p | not pkgs_all.include? p }
pkgs_reqd = pkgs_reqd.collect { | p | project.package(p) }
if project.application
pkgs_reqd_and_app = pkgs_reqd + [ project.application ]
else
pkgs_reqd_and_app = pkgs_reqd
end
info "Required packages (in topological order):"
pkgs_reqd.each do | pkg |
info " #{pkg.name}"
end
# compile task
if project.application
task :'compile:application' => project.application.name
else
task :'compile:application'
end
info "Defining task for packages..."
pkgs_reqd_and_app.each do | pkg |
info "Defining task for package #{pkg.name}"
if unix? #and not File.exist? BUILD_DIR / pkg.directory / 'makefile'
task pkg.name => [ BUILD_DIR / pkg.directory / 'makefile' ]
file BUILD_DIR / pkg.directory / 'makefile' do
chdir BUILD_DIR / pkg.directory do
if not system "sh #{ pkg.top() / 'stx' / 'rules' / 'stmkmf'}"
raise Exception.new("Canmot run stmkmf for #{pkg.directory}")
end
end
end
end
#require 'find'
#[ 'bitmaps', 'resources' ].each do | dir |
# path = BUILD_DIR / pkg.directory() / dir
# if File.exist?(path)
# Find.find(File.expand_path(path)) do | file |
# if FileTest.directory?(file)
# if (File.basename(file) == '..') || (File.basename(file) == '.')
# Find.prune # Don't look any further into this directory.
# else
# if File.exists?(File.join(file, '.svn'))
# rm_rf File.join(file, '.svn')
# #Find.prune
# end
# end
# end
# end
# end
#end
task "#{pkg.name}" => [ "#{pkg.name}:pre", "#{pkg.name}:main", "#{pkg.name}:post" ]
task "#{pkg.name}:pre"
task "#{pkg.name}:post"
task "#{pkg.name}:main" do | t |
make_vars = ""
d = win32? ? '-D' : ''
q = win32? ? '"' : "'"
if unix?
make_vars += "STC=#{STC}"
end
if pkg.application? and not win32?
liblist=''
libobjs=''
link_libobjs=''
pkgs_reqd.each do | p |
if not p.application?
if p.link
liblist += "#{p.dll_name_without_suffix()} "
libobjs += "#{File.join(pkg.top() , p.directory(), p.dll_name())} "
link_libobjs += "#{p.dll_name()} "
end
end
end
make_vars += " #{q}#{d}LIBLIST=#{liblist}#{q}"
make_vars += " #{q}#{d}LIBOBJS=#{libobjs}#{q}"
make_vars += " #{q}#{d}LINK_LIBOBJS=#{link_libobjs}#{q}"
end
# Update stc flags,
stc_flags = pkg.stc_flags
if stc_flags
make_vars += " #{q}#{d}STC_CMD_OPT=#{stc_flags}#{q}"
end
if File.exist? BUILD_DIR / pkg.directory / 'GNUmakefile'
rm BUILD_DIR / pkg.directory / 'GNUmakefile'
end
info "Compiling #{pkg.name}..."
make_vars = "#{make_vars} #{DEBUG}"
chdir BUILD_DIR / pkg.directory do
if pkg.application? and win32?
make 'exe'
make 'RESOURCEFILES'
else
# Somewhat stupid detection whether we run recent St/X or not...
if File.exist? BUILD_DIR / 'stx' / 'libbasic2' / 'Makefile.init'
make "#{make_vars} full"
else
make "#{make_vars}"
end
end
end
if pkg.application? and unix?
chdir BUILD_DIR / 'stx' / 'librun' do
make
end
end
end
if pkg.application?
if win32?
task pkg.name => BUILD_DIR / pkg.directory / 'modules.stx'
task BUILD_DIR / pkg.directory / 'modules.stx' do | t |
rm t.name if File.exist? t.name
File.open(t.name, 'w') do | f |
pkgs_reqd.each do | p |
if not p.application? and File.exist? BUILD_DIR / p.directory / OBJ_DIR / p.dll_name()
f.puts p.dll_name_without_suffix()
end
end
end
end
pkgs_reqd.each do | p |
if not p.application?
task pkg.name => BUILD_DIR / pkg.directory / p.dll_name()
file BUILD_DIR / pkg.directory / p.dll_name() => BUILD_DIR / p.directory / OBJ_DIR / p.dll_name() do
cp BUILD_DIR / p.directory / OBJ_DIR / p.dll_name(),
BUILD_DIR / pkg.directory / p.dll_name()
end
end
if win32_wine?
file BUILD_DIR / pkg.directory / p.dll_name() do
cp BUILD_DIR / p.directory / OBJ_DIR / p.dll_name(),
BUILD_DIR / pkg.directory / p.dll_name()
end
end
end
else # UNIX
task "#{pkg.name}:main" => BUILD_DIR / pkg.directory / 'modulList.stc'
task BUILD_DIR / pkg.directory / 'modulList.stc' do | t |
rm t.name if File.exist? t.name
end
task "#{pkg.name}:main" => BUILD_DIR / pkg.directory / 'modulList.c'
task BUILD_DIR / pkg.directory / 'modulList.c' do | t |
rm t.name if File.exist? t.name
end
end
end
end
end