Makefiles: use our own makefiles rather than eXept's
...found in `stx/rules`. eXept's makefiles doesn't really
fit Smalltalk/X jv-branch needs - they're cluttered with
workarounds for long unsupported tools and platforms. In the
past we had to monkey-patch them here and there.
From this commit on, building requires GNU Make on UNUX-like
and GCC or Clang toolchain on both UNIX-like and Windows.
There we use MSYS2 environment.
This is a followup for 6fcb351d23a7.
desc "Compile project"
task :'compile' => :'compile:all'
STX_TOP_DIR = BUILD_DIR / 'stx'
STX_CONF_DIR = STX_TOP_DIR / 'configurations'
STX_RULES_DIR = STX_TOP_DIR / 'rules'
if win32?
STC = STX_TOP_DIR / 'stc' / 'stc.exe'
LIBRUN = STX_TOP_DIR / 'librun' / 'objmingw' / 'librun.dll'
else
STC = STX_TOP_DIR / 'stc' / 'stc'
LIBRUN = STX_TOP_DIR / 'librun' / 'librun.so'
end
# Return true if stx:stc and stx:librun sources should be removed as soon
# as STC or librun is built. False otherwise (sources are not removed by
# rakefiles)
#
# Indeed this is a feeble protection as it's easy to trick this method. But
# the goal is not to protect sources but rather have a secondaty measure to
# avoid sources to leak (for exaple, due to a bug in packaging scripts).
# Unathorized subjects should not be able to checkout sources in first instance.
def should_remove_librun_and_stc_sources
return ! (core_developer? or ENV['RETAIN_STX_AND_LIBRUN_SOURCE'] == 'yespleaseretain!')
end
def rm_rf_all_in_except(directory, exceptions = [])
if File.directory? directory then
Dir.foreach(directory) do | each |
if each != '.' and each != '..' and not exceptions.include? each
rm_rf File.join(directory, each)
end
end
else
rm_f directory
end
end
if unix?
STC_BINARY_FILES = [
'cpu_alpha.h',
'cpu_arm.h',
'cpu_hppa.h',
'cpu_i386.h',
'cpu_x86_64.h',
'cpu_ia64.h',
'cpu_mc68k.h',
'cpu_mc88k.h',
'cpu_mips.h',
'cpu_ns32k.h',
'cpu_power.h',
'cpu_s390.h',
'cpu_sparc.h',
'cpu_vax.h',
'stc.h',
'stcIntern.h',
'stcVMdata.h',
'stcVMoffsets.h',
'stxAsmMacros.h',
'stxNames.h',
'stxOSDefs.h',
'stxTypeMacros.h',
'symbols.stc.seed',
'version.h',
'README',
#unix specific
'stx-config.sh',
'linuxIntern.h',
'macIntern.h',
'Make.proto',
'stc',
'stc.1',
]
LIBRUN_BINARY_FILES1 = [
'libffi-3.2.1',
'md5.h',
'mcompiler.h',
'main.c',
'librun.so',
'librun.a',
'symlist.c',
'Make.proto',
'makefile',
]
LIBRUN_BINARY_FILES2 = []
elsif win32?
STC_BINARY_FILES = [
'cpu_alpha.h',
'cpu_arm.h',
'cpu_hppa.h',
'cpu_i386.h',
'cpu_x86_64.h',
'cpu_ia64.h',
'cpu_mc68k.h',
'cpu_mc88k.h',
'cpu_mips.h',
'cpu_ns32k.h',
'cpu_power.h',
'cpu_s390.h',
'cpu_sparc.h',
'cpu_vax.h',
'stc.h',
'stcIntern.h',
'stcVMdata.h',
'stcVMoffsets.h',
'stxAsmMacros.h',
'stxNames.h',
'stxOSDefs.h',
'stxTypeMacros.h',
'symbols.stc.seed',
'version.h',
'README',
#windows specific
'stx-config.bat',
'mingwmake.bat',
'ntIntern.h',
'nt.h',
'Make.proto',
'stc.exe',
]
LIBRUN_BINARY_FILES1 = [
'libffi-3.2.1',
'md5.h',
'mcompiler.h',
'main.c',
'objmingw',
'bc.mak',
'mingwmake.bat',
'buildDate.h',
'genDate.com',
]
LIBRUN_BINARY_FILES2 = [
'librun.dll',
'librun.lib',
]
else
raise Exception.new("Unsupported platform")
end
def cleanup_stc()
if should_remove_librun_and_stc_sources()
puts "Cleaning up stc..."
begin
rm_rf_all_in_except(STX_TOP_DIR / 'stc', STC_BINARY_FILES)
rescue
# When something goes wrong, be safe and remove whole directory
rm_rf STX_TOP_DIR / 'stc'
end
end
end
def cleanup_librun()
if should_remove_librun_and_stc_sources()
puts "Cleaning up librun..."
begin
rm_rf_all_in_except(STX_TOP_DIR / 'librun', LIBRUN_BINARY_FILES1)
if win32? then
rm_rf_all_in_except(STX_TOP_DIR / 'librun' / 'objmingw', LIBRUN_BINARY_FILES2)
end
rescue
# When something goes wrong, be safe and remove whole directory
rm_rf STX_TOP_DIR / 'librun'
end
end
end
# Setup flags for GCC (both, real GCC and MinGW)
GCC_CFLAGS_OPT = ARCH == 'i386' ? '-O' : ''
GCC_CFLAGS_DBG = core_developer? ? '-ggdb3' : ''
GCC_CFLAGS_PIC = win32? ? '' : '-fPIC'
GCC_CFLAGS = "-pipe -fno-omit-frame-pointer -fno-stack-protector -fno-strict-aliasing -fwrapv #{GCC_CFLAGS_PIC} #{GCC_CFLAGS_OPT} #{GCC_CFLAGS_DBG}"
# Sigh, for MINGW 5.x.x coming with MSYS2 we have to force C language as
# Borland make and build files are using funny suffixes to confuse GCC's
# language detection. Triple sigh here!
GCC_CFLAGS += " -x c" if win32?
namespace :'compile' do
task :'all' => [ :'prereq', :'pre', :'main', :'post' ]
task :'pre'
task :'post'
task :'prereq' => [ :'setup' ]
task :'main' => [
:'config',
:'libraries',
:'stc',
:'librun',
:'application',
]
task :'config' => [ STX_TOP_DIR / 'include' ]
directory STX_TOP_DIR / 'include'
task :'application' => :'setup:dependencies'
if unix?
mkdir_p STX_CONF_DIR
STX_CONF_DIR / 'vendorConf',
STX_CONF_DIR / 'myConf' ]
directory STX_CONF_DIR do | t |
mkdir_p t.name()
end
directory STX_CONF_DIR / 'COMMON' do | t |
mkdir_p t.name()
end
directory STX_CONF_DIR / 'COMMON' / 'defines' => STX_CONF_DIR / 'COMMON' do | t |
File.open(t.name(), "w") do | f |
f.puts <<-CONTENTS
# Do not edit! Automatically generated by rake (rakelib/#{__FILE__})
#
# Nothing here, all "common" definitions are included in config file
# (`config-<OS>-<ARCH>.make`)
CONTENTS
end
end
file STX_CONF_DIR / 'vendorConf' => STX_CONF_DIR do | t |
makelib_dir = Pathname.new(File.expand_path('makelib')).relative_path_from(Pathname.new(BUILD_DIR / 'stx' ))
os = nil
case
when linux?
os = 'linux'
else
raise Exveption.new("Unssuported operating system")
end
File.open(t.name(), "w") do | f |
f.puts <<-CONTENTS
# Do not edit! Automatically generated by rake (rakelib/#{__FILE__})
#
TOP ?= #{BUILD_DIR / 'stx'}
MAKELIB ?= $(TOP)/#{makelib_dir}
include $(MAKELIB)/config-#{os}-#{ARCH}.make
CONTENTS
end
end
file STX_CONF_DIR / 'myConf' => STX_CONF_DIR do | t |
File.open(t.name(), "w") do | f |
f.puts <<-CONTENTS
# Local modifications / additions specific to this very build, if needed.
#
CONTENTS
end
end
end
rule 'makefile' do | t |
if File.exist?(File.dirname(t.name) / 'GNUmakefile')
rm (File.dirname(t.name) / 'GNUmakefile')
end
chdir File.dirname(t.name) do
sh "'#{STX_TOP_DIR / 'rules' / 'stmkmf'}'"
end
end
task :stc do
if linux? and x86_64? and ARCH == 'i386'
stx_make_flags="STC_LEXLIB=libfl/libfl_pic.a"
else
stx_make_flags=""
end
chdir STX_TOP_DIR / 'stc' do
begin
make stx_make_flags
cleanup_stc()
rescue Exception => e
cleanup_stc()
cleanup_librun()
error "Cannot compile stx:stc: #{e.description}"
end
end
if not File.exist? STX_TOP_DIR / 'include' / 'stx-config.h' then
cp STX_TOP_DIR / 'stc' / 'stx-config.h' , STX_TOP_DIR / 'include' / 'stx-config.h'
end
if not File.exist? STC
cleanup_stc()
cleanup_librun()
error "Cannot compile stx:stc"
end
end
task :librun do
chdir STX_TOP_DIR / 'librun' do
begin
begin
if win32_wine?
if not File.exist? 'libffi' / 'build_win32' / 'objbc'
mkdir 'libffi' / 'build_win32' / 'objbc'
end
end
# A workaround for Windows 10 & ancient Borland make which
# tend to crash there when trying to recompile already compiled
# librun. Sigh, we have to move away from it as soon as possible!
if win32? and (File.exist? 'stxmain.c') then
touch "stxmain.c"
end
make
cleanup_librun()
rescue Exception => e
cleanup_stc()
cleanup_librun()
error "Cannot compile stx:librun: #{e.description}"
end
end
end
end
if unix?
task :stc => STX_TOP_DIR / 'stc' / 'makefile'
task :librun => STX_TOP_DIR / 'librun' / 'makefile'
end
if win32? and TOOLCHAIN == 'bcc'
directory STX_TOP_DIR / 'lib' / 'bc'
task :librun => STX_TOP_DIR / 'lib' / 'bc'
end
task :'libraries'
if unix?
vogl_dir = STX_TOP_DIR / 'support' / 'VGL' / 'vogl'
task 'libraries' => [ vogl_dir / 'src' / 'libvogl.a' ]
file vogl_dir / 'src' / 'libvogl.a' => [ vogl_dir / 'makefile' ] do
chdir STX_TOP_DIR / 'support' / 'VGL' / 'vogl' do
make
end
end
end
end
task "stx:librun:symbols"
#
# Various compilation hacks here and there (sigh)
#
desc "Update the VM symbol database"
task 'stx:librun:symbols' do | task |
symbols_stc = BUILD_DIR / 'stx' / 'include' / 'symbols.stc'
if unix?
# UNIX VMs have the symbol database built into the binary as
# static data so we need to recompile the VM
stx_librun = project.package('stx:librun')
stx_librun_dll = BUILD_DIR / stx_librun.directory() / OBJ_DIR / stx_librun.dll_name()
if not uptodate?(stx_librun_dll, [ symbols_stc ]) then
Rake::Task["stx:librun"].reenable()
Rake::Task["stx:librun"].invoke()
end
elsif win32?
# Windows VM reads the symbol database from a file `symbols.stc` located
# alongside the program executable so we need to copy that file
app = project.application
symbols_stc_in_app_directory = BUILD_DIR / app.directory() / 'symbols.stc'
if not uptodate?(symbols_stc_in_app_directory, [ symbols_stc ]) then
cp symbols_stc, symbols_stc_in_app_directory
end
end
task.reenable()
end
if unix?
# A hack for Debian (and possibly other Linux distros) that does not ship
# 32bit libodbc.a / libodbcinst.a. Link directly against .so
task :'stx:libdb/libodbc:pre' do
sed('-lodbc -lodbcinst' , '-l:libodbc.so.2 -l:libodbcinst.so.2', BUILD_DIR / 'stx' / 'libdb' / 'libodbc' / 'Make.proto', true)
end
end