scummvm/backends/platform/symbian/symbian_builder/mmp_gen.py
2021-08-20 19:45:01 +02:00

349 lines
10 KiB
Python

# ScummVM - Graphic Adventure Engine
# Copyright (C) 2020 Stryzhniou Fiodar
# ScummVM is the legal property of its developers, whose names
# are too numerous to list here. Please refer to the COPYRIGHT
# file distributed with this source distribution.
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
from __future__ import with_statement
import os, shutil
from collections import defaultdict as defdict
from common_names import *
#ignore unfinished engines in release build
def CheckForRelease(line_):
if 'no' in line_:
return build != 'release'
else:
return True
# This function is frozen! Don't edit!
def processengine(path):
with open(os.path.join(path, "configure.engine")) as f:
ff = f.readlines()
ff = [n for n in ff if not n.startswith('# ')] #exclude comments
ff = [n for n in ff if len(n) > 2]
ff = [n.split('"', 2) for n in ff]
try:
tt = [n[0] + n[2] for n in ff]
ff = tt
except IndexError:
print "Something wrong here:"
print ff
return None
f = [n.split() for n in ff]
if f[0][2] == 'no' and build == "release":
return None
# print "MACRO ENABLE_%s // LIB:scummvm_%s.lib" %(f[0][1].upper(), f[0][1])
buildparam = ["MACRO ENABLE_%s // LIB:scummvm_%s.lib" %(f[0][1].upper(), f[0][1])]
libname = ["STATICLIBRARY scummvm_%s.lib" %f[0][1]]
if len(f) == 1:
return [buildparam, libname]
if len(f[0]) > 3:
f = f[1:]
for i in f:
if CheckForRelease(i[2]):
# print " MACRO ENABLE_%s // Subengine" %i[1].upper()
buildparam += [" MACRO ENABLE_%s // Subengine" %i[1].upper()]
return [buildparam, libname]
# This function is frozen! Don't edit!
def processModule_mk(path, buildparams):
with open(os.path.join(path, "module.mk")) as ff:
f = ff.readlines()
src = []
addsrc = None
for i in f:
#add engine base source code first
if "MODULE_OBJS" in i:
if addsrc is None:
addsrc = True
elif "ifdef ENABLE_" in i:
for x in buildparams:
if "MACRO %s"%i.strip()[6:] in x:
addsrc = True
src += ["// Subengine %s" %x[18:]]
elif "KYRARPG_COMMON_OBJ" in i: #special case for kyra engine
addsrc = True
elif "DETECT_OBJS" in i:
cpp = i.rstrip()
cpp = cpp.rsplit('$')[-1]
cpp = cpp[9:-2]
src += ["SOURCE %s.cpp" %cpp]
elif addsrc is True:
# if i.endswith(".o \\"): # this dont work, why?
if ".o \\" in i[-5:]:
src += ["SOURCE %s.cpp" %i[1:-5]]
elif ".o" in i[-3:]:
src += ["SOURCE %s.cpp" %i[1:-3]]
elif len(i) == 1:
addsrc = False
return src
# Add per engine fixes
libc_engines = ("ags", "bladerunner", "glk", "illusions", "nancy", "stark", "titanic", "ultima")
def CheckEngine(lst, game):
if game == "sword25":
return None
if game == "testbed":
return None
if game in libc_engines:
lst = lst + "\nOPTION GCCE -I'/Symbian/S60_5th_Edition_SDK_v1.0/epoc32/include/libc'\n"
if game == "zvision":
lst = lst + "\nMACRO USE_A52\n"
return lst
def ProcessDup(src):
"""Function saves file duplicates with new name, origin remains as is."""
ourDict = defdict(list)
destDict = {}
for item in src:
if "SOURCE" in item:
t = item.split()[1]
destDict[t] = t
m = os.path.split(t)
ourDict.setdefault(m[1], []).append(m[0])
ourDict = dict((k, v) for k, v in ourDict.iteritems() if len(v) > 1)
result = src
if( len(ourDict.values()) > 0):
result = []
fixed = FindDup(ourDict)
for item in src:
if "SOURCE" in item:
dst = item.split()[1]
if dst in fixed:
d = item.replace(dst, fixed[dst])
result.append(d)
else:
result.append(item)
ourDict.clear()
return result
def FindDup(files):
val = {}
# print "File duplicates found:\n %s" %files
keys = files.keys()
# print "for keys: %s" %keys
for k in keys:
for v in files[k]:
if len(v) > 0:
t = MakeRenamePair(v, k)
src = os.path.join(currentEngine, t[0])
dst = os.path.join(currentEngine, t[1])
val[t[0]] = t[1]
# if(os.path.exists(dst)): # todo: fix possible file duplicates
# dst = str(hash(dst)) + dst
# print "Rename file %s to %s" %(src, dst)
shutil.copyfile(src, dst)
t = open(dst) # Fail if file not exist
t.close()
return val
def MakeRenamePair(val, key):
# nuvie/core + events.cpp -> nuvie_core + events.cpp -> nuvie/core + nuvie_core_events.cpp -> nuvie/core/nuvie_core_events.cpp
v = val.replace("/", "_")
k = v + "_" + key # nuvie_core_events.cpp
newFile = val + "/" + k #nuvie/core/nuvie_core_events.cpp
oldFile = val + "/" + key
#if newFile exists: nuvie_core_events.cpp -> (hash)_nuvie_core_events.cpp
return [oldFile, newFile]
# This function is frozen! Don't edit!
def SafeWriteFile(path, mode, data):
"""Save list elments as strings. Save strings as is"""
with open(path, mode) as f:
if type(data) is list:
for s in data:
f.write(s + '\n')
else:
f.write(data)
def FilterUltima(src):
src = [x for x in src if "nuvie" not in x] #Ultima VI
src = [x for x in src if "ultima4" not in x]
print "Exclude nuvie and ultima4 engines from detection_tables.h and detection.cpp!"
return src
def FilterGrim(src):
src += ["#if !defined(WINS)"]
src += ["SOURCE movie/codecs/blocky8ARM.s"]
src += ["#endif"]
return src
def FilterScumm(src):
src += ["#if !defined(WINS)"]
src += ["SOURCE proc3ARM.s"]
src += ["SOURCE gfxARM.s"]
src += ["SOURCE smush/codec47ARM.s"]
src += ["#endif"]
return src
def FilterSrcs(src, engine):
if "grim" in engine:
return FilterGrim(src)
if "ultima" in engine:
return FilterUltima(src)
if "scumm" in engine:
return FilterScumm(src)
# if "" in engine:
# return Filter(src)
return src
guard_macro = "#ifdef SCUMMVM_PT_%s\n#endif // SCUMMVM_PT_%s\n"
ro_warning = """
// This is autogenerated file.\n\n
/* Warning! Carbide can silently change file.
Set read-onle attribute after manual update!!! */
"""
def MakeMMP(engine):
global firstRun, currentEngine
print "Start processing engine: %s" %engine
pth = os.path.join(pt, engine)
currentEngine = pth
tt = processengine(pth)
if tt is None:
return
macrolist = tt[0]
staticlib = tt[1]
src = processModule_mk(pth, macrolist)
src = ProcessDup(src)
src = FilterSrcs(src, engine)
mmp = """TARGET scummvm_%s.lib
TARGETTYPE lib\n
#include "../S60v3/build_config.mmh"
#include "build_parts.mmh"
#include "../S60v3/macros.mmh"\n
USERINCLUDE ..\..\..\..\engines\%s\n
// *** SOURCE files
SOURCEPATH ..\..\..\..\engines\%s\n
""" %(engine, engine, engine)
print "TARGET scummvm_%s.lib" %engine
mmp = CheckEngine(mmp, engine)
if mmp is None:
return
plugins_table = """
#if PLUGIN_ENABLED_STATIC(%s)
LINK_PLUGIN(%s)
#endif
""" %(engine.upper(), engine.upper())
detection_table = """
#if defined(ENABLE_%s) || defined(DETECTION_FULL)
LINK_PLUGIN(%s_DETECTION)
#endif
""" %(engine.upper(), engine.upper())
bldinf = os.path.join(local, "bld.inf")
mmpfile = os.path.join(local, "%s.mmp" %engine)
ptable = os.path.join(pt, "plugins_table.h")
dtable = os.path.join(pt, "detection_table.h")
macros = os.path.join(local, "macros.mmh")
engines = os.path.join(local, "engines.mmh")
#create files and add bld.inf header
if firstRun is True:
SafeWriteFile(bldinf, 'w', "PRJ_MMPFILES\n")
if(build == 'release'):
SafeWriteFile(macros, 'w', "MACRO RELEASE_BUILD\n")
guard_macros = [guard_macro %(i + 1, i + 1) for i in range(len(uids))]
SafeWriteFile(macros, 'w', ro_warning)
SafeWriteFile(macros, 'a', guard_macros)
SafeWriteFile(ptable, 'w', "// This is autogenerated file.\n")
SafeWriteFile(dtable, 'w', "// This is autogenerated file.\n")
SafeWriteFile(engines, 'w', ro_warning)
SafeWriteFile(engines, 'a', guard_macros)
firstRun = False
SafeWriteFile(mmpfile, 'w', mmp)
SafeWriteFile(mmpfile, 'a', src)
SafeWriteFile(bldinf, 'a', "%s.mmp\n" %engine)
SafeWriteFile(macros, 'a', macrolist)
SafeWriteFile(engines, 'a', staticlib)
SafeWriteFile(ptable, 'a', plugins_table)
SafeWriteFile(dtable, 'a', detection_table)
currentEngine = None
print "End processing\n"
firstRun = True
currentEngine = None
pt = '..\..\..\engines'
local = mmps
# pt = 'e:\Scu\engines'
# local = pt
def count_sc_parts():
t = []
for i in range(len(uids)):
d = "#define SCUMMVM_PT_%d" %(i+1)
t.append(d)
pth = os.path.join(local, "build_parts.mmh")
SafeWriteFile(pth, 'w', ro_warning)
SafeWriteFile(pth, 'a', t)
def create_engine_mmps(arg = 'full'):
global build
build = arg
if not os.path.exists(local):
os.mkdir(local)
if(os.path.isfile(local)):
raise TypeError("Expected dir but file found %s" %pt)
if(local != pt):
if(os.path.isdir(local)):
try:
shutil.rmtree(local)
os.mkdir(local)
except: pass
t = os.listdir(pt)
[MakeMMP(m) for m in t if os.path.isdir(os.path.join(pt, m))]
count_sc_parts()
if __name__ == "__main__":
create_engine_mmps()