rakelib/setup.rake
author Jan Vrany <jan.vrany@fit.cvut.cz>
Sat, 10 Dec 2016 20:44:26 +0000
changeset 98 e8a75e807ff2
parent 97 33cf3197acb5
child 101 32f9287b419a
permissions -rw-r--r--
Oops, make sure `REPOSITORYSET` value is written to `config.rb`

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? TMP_DIR or TMP_DIR = 'tmp'
defined? DEBUG or DEBUG = nil

if win32?
  ENV['BCB'] = 'C:\\Borland\\BCC55' if not ENV['BCB']
end

if File.exist? 'config.rb'
  load 'config.rb'
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']
    case arch
    when "i586"
      ARCH = 'i386'
    when "i686"
      ARCH = 'i386'
    else
      ARCH = arch
    end
  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="mingw32"
      end
    else
      raise new Exception("Unsupported operating system")    
    end
  end
end

if not defined? REPOSITORYSET
  REPOSITORYSET = (ENV['REPOSITORYSET'] || 'default')
end

if not File.exist? 'config.rb'
  if defined? PROJECT
    File.open('config.rb', 'w') do | f |
      f.puts <<COMMENT
# This file contans a default build configuration. It is created automatically
# when `rake` is called for the very first time. You may still override values
# on command line, i.e., 
#
#     rake PROJECT=some-other-project 
#
# This file SHOULD NOT be checked in a repository. 
#
COMMENT
      f.puts "PROJECT='#{PROJECT}' if not defined? PROJECT"
      f.puts "ARCH='#{ARCH}' if not defined? ARCH"
      f.puts "REPOSITORYSET='#{REPOSITORYSET}' if not defined? REPOSITORYSET"
      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 File.exist? 'C:\mingw64\bin' then
    ENV['MINGW_DIR'] ='C:\MINGW64'
    ENV['USEMINGW_ARG'] = '-DUSEMINGW64'
  elsif File.exist? 'C:\MSYS64\MINGW64\bin\gcc.exe'
    ENV['MINGW_DIR'] ='C:\MSYS64\MINGW64'
    ENV['USEMINGW_ARG'] = '-DUSEMINGW64'
  else
  	raise Exception.new("MINGW64 nor MSYS2 found in C:\\MinGW64 nor C:\\MSYS64!")
  end
  ENV['MINGW'] = '__MINGW64__'
  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 File.exist? 'C:\mingw\bin' then
    ENV['MINGW_DIR'] ='C:\MINGW'
    ENV['USEMINGW_ARG'] = '-DUSEMINGW32'  
  elsif File.exist? 'C:\MSYS64\MINGW32\bin\gcc.exe'
    ENV['MINGW_DIR'] ='C:\MSYS64\MINGW32'
    ENV['USEMINGW_ARG'] = '-DUSEMINGW32'  
    system 'set'
  elsif File.exist? 'C:\MSYS\MINGW32\bin\gcc.exe'
    ENV['MINGW_DIR'] ='C:\MSYS\MINGW32'
    ENV['USEMINGW_ARG'] = '-DUSEMINGW32'  
  else    
    raise Exception.new("MINGW32 nor MSYS2 found in C:\\MinGW nor C:\\MSYS64 nor C:\\MSYS!")
  end
  ENV['MINGW'] = '__MINGW32__'
  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:dependencies' => :'checkout' do
  project.packages.each do | pkg |        
    if File.exist? (BUILD_DIR / pkg.directory() / pkg.project_definition_file_name()) then
	  if not pkg.test_package? then
        task "#{project.application.name}:dependencies" => pkg.name
        task "#{pkg.name}:dependencies" => pkg.prereqs(mandatory: true)
      end
    end
  end
end

task :'setup:tasks' => :'setup:tasks:internal'

task :'setup:tasks:internal' => :'setup:project' do

  project.tasks.each do | t |
    t.define!
  end

  # compile task
  if project.application
    task :'compile:application' => project.application.name
  else
    task :'compile:application'
  end

  info "Defining tasks for packages..."

  project.packages_and_application.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}:dependencies", "#{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=''
        project.packages.each do | p |
          if File.exist? (BUILD_DIR / p.directory() / p.project_definition_file_name()) then
            if not p.application? and p.link and not p.test_package?
              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 |
            project.packages.each do | p |
              if not p.application? and p.link and not p.test_package? and File.exist? BUILD_DIR / p.directory / OBJ_DIR / p.dll_name()
                f.puts p.dll_name_without_suffix()
              end
            end
          end
        end

        project.packages.each do | p |
          if not p.application? and not p.test_package?
            task pkg.name => BUILD_DIR / pkg.directory / p.dll_name()

            file BUILD_DIR / pkg.directory / p.dll_name() do
              if not p.application? and p.link and not p.test_package? and File.exist? BUILD_DIR / p.directory / OBJ_DIR / p.dll_name()
                cp BUILD_DIR / p.directory / OBJ_DIR / p.dll_name(),
                   BUILD_DIR / pkg.directory / p.dll_name()
              end                   
            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