switch gbuild-to-ide to use gbuildtojson

Change-Id: Ic3ac11683a44e946e844e18a7670fa7baf46110a
Reviewed-on: https://gerrit.libreoffice.org/31175
Tested-by: Björn Michaelsen <bjoern.michaelsen@canonical.com>
Reviewed-by: Luke Benes <lukebenes@hotmail.com>
Reviewed-by: Björn Michaelsen <bjoern.michaelsen@canonical.com>
This commit is contained in:
Bjoern Michaelsen
2016-11-24 22:04:02 +01:00
committed by Björn Michaelsen
parent a62740c668
commit 78547c3374
2 changed files with 78 additions and 194 deletions

View File

@@ -413,8 +413,8 @@ dump-deps-sort:
@$(SRCDIR)/bin/module-deps.pl -t $(MAKE) $(SRCDIR)/Makefile.gbuild @$(SRCDIR)/bin/module-deps.pl -t $(MAKE) $(SRCDIR)/Makefile.gbuild
define gb_Top_GbuildToIdeIntegration define gb_Top_GbuildToIdeIntegration
$(1)-ide-integration: $(1)-ide-integration: gbuildtojson
cd $(SRCDIR) && (LC_MESSAGES=C $(MAKE) cmd="$(MAKE) -npf Makefile.gbuild all" cmd || true) | $(SRCDIR)/bin/gbuild-to-ide --ide $(1) cd $(SRCDIR) && $(SRCDIR)/bin/gbuild-to-ide --ide $(1) --make $(MAKE)
endef endef

View File

@@ -21,21 +21,7 @@ import xml.dom.minidom as minidom
import traceback import traceback
class GbuildParserState:
def __init__(self):
self.target = None
self.ilib = None
self.include = []
self.defs = {}
self.cxxobjects = []
self.cxxflags = []
self.linked_libs = []
self.include_sys = []
class GbuildLinkTarget: class GbuildLinkTarget:
def __init__(self, name, location, include, include_sys, defs, cxxobjects, cxxflags, linked_libs): def __init__(self, name, location, include, include_sys, defs, cxxobjects, cxxflags, linked_libs):
(self.name, self.location, self.include, self.include_sys, self.defs, self.cxxobjects, self.cxxflags, self.linked_libs) = ( (self.name, self.location, self.include, self.include_sys, self.defs, self.cxxobjects, self.cxxflags, self.linked_libs) = (
name, location, include, include_sys, defs, cxxobjects, cxxflags, linked_libs) name, location, include, include_sys, defs, cxxobjects, cxxflags, linked_libs)
@@ -53,7 +39,6 @@ class GbuildLinkTarget:
class GbuildLib(GbuildLinkTarget): class GbuildLib(GbuildLinkTarget):
def __init__(self, name, library, location, include, include_sys, defs, cxxobjects, cxxflags, linked_libs): def __init__(self, name, library, location, include, include_sys, defs, cxxobjects, cxxflags, linked_libs):
GbuildLinkTarget.__init__(self, name, location, include, include_sys, defs, cxxobjects, cxxflags, linked_libs) GbuildLinkTarget.__init__(self, name, location, include, include_sys, defs, cxxobjects, cxxflags, linked_libs)
self.library = library self.library = library
@@ -70,7 +55,6 @@ class GbuildLib(GbuildLinkTarget):
class GbuildExe(GbuildLinkTarget): class GbuildExe(GbuildLinkTarget):
def __init__(self, name, executable, location, include, include_sys, defs, cxxobjects, cxxflags, linked_libs): def __init__(self, name, executable, location, include, include_sys, defs, cxxobjects, cxxflags, linked_libs):
GbuildLinkTarget.__init__(self, name, location, include, include_sys, defs, cxxobjects, cxxflags, linked_libs) GbuildLinkTarget.__init__(self, name, location, include, include_sys, defs, cxxobjects, cxxflags, linked_libs)
self.executable = executable self.executable = executable
@@ -84,186 +68,85 @@ class GbuildExe(GbuildLinkTarget):
class GbuildParser: class GbuildParser:
makecmdpattern = re.compile('^MAKE_COMMAND := (.*)') def __init__(self, makecmd):
srcdirpattern = re.compile('^SRCDIR = (.*)') self.makecmd = makecmd
builddirpattern = re.compile('^BUILDDIR = (.*)') self.binpath = os.path.dirname(os.environ['GPERF']) # woha, this is quite a hack
instdirpattern = re.compile('^INSTDIR = (.*)') (self.srcdir, self.builddir, self.instdir, self.workdir) = (os.environ['SRCDIR'], os.environ['BUILDDIR'], os.environ['INSTDIR'], os.environ['WORKDIR'])
binpathpattern = re.compile('^GPERF = (.*)gperf(.exe)?') (self.libs, self.exes, self.modulenamelist) = ([], [], [])
libnamespattern = re.compile('^gb_Library_ILIBFILENAMES := (.*)') (self.libnames, self.exenames, self.target_by_path, self.target_by_location) = ({}, {}, {}, {})
exenamepattern = re.compile('^gb_Executable_FILENAMES_FOR_BUILD := (.*)')
rulepattern = re.compile('^(.+?):( .*)?$')
libpattern = re.compile('# [a-z]+ to execute \(from [\'`](.*)/Library_(.*)\.mk\', line [0-9]*\):')
exepattern = re.compile('# [a-z]+ to execute \(from [\'`](.*)/Executable_(.*)\.mk\', line [0-9]*\):')
includepattern = re.compile('-I(\S+)') includepattern = re.compile('-I(\S+)')
isystempattern = re.compile('-isystem\s*(\S+)') isystempattern = re.compile('-isystem\s*(\S+)')
defspattern = re.compile('# DEFS := (.*)')
cxxpattern = re.compile('# CXXOBJECTS := (.*)')
linkedlibspattern = re.compile('# LINKED_LIBS := (.*)')
ilibpattern = re.compile('# ILIBTARGET := (.*)')
warningpattern = re.compile('-W\S+') warningpattern = re.compile('-W\S+')
libpattern = re.compile('Library_(.*)\.mk')
exepattern = re.compile('Executable_(.*)\.mk')
def __init__(self): @staticmethod
(self.makecmd, self.srcdir, self.builddir, self.instdir, self.libs, self.exes, def __split_includes(includes):
self.libnames, self.exenames, self.target_by_path, self.target_by_location, self.modulenamelist) = ('', '', '', '', [], [], {}, {}, {}, {}, []) foundisystem = GbuildParser.isystempattern.findall(includes)
foundincludes = [includeswitch.strip() for includeswitch in GbuildParser.includepattern.findall(includes) if
len(includeswitch) > 2]
return (foundincludes, foundisystem)
def __mapping_to_dict(self, mapping): @staticmethod
mapping_dict = {} def __split_objs(objsline):
for item in mapping.split(' '): return [obj for obj in objsline.strip().split(' ') if len(obj) > 0 and obj != 'CXXOBJECTS' and obj != '+=']
library, target = item.split(':')
mapping_dict[target] = library
return mapping_dict
def _parse_hash_old(self, line, state): @staticmethod
libmatch = GbuildParser.libpattern.match(line) def __split_defs(defsline):
if libmatch: defs = {}
libname = self.libnames.get(state.ilib, None) alldefs = [defswitch.strip()[2:] for defswitch in defsline.strip().split(' ') if len(defswitch) > 2]
if state.cxxobjects: for d in alldefs:
self.libs.append( defparts = d.split('=')
GbuildLib(libmatch.group(2), libname, libmatch.group(1), if len(defparts) == 1:
state.include, state.include_sys, state.defs, state.cxxobjects, defparts.append(None)
state.cxxflags, state.linked_libs)) defs[defparts[0]] = defparts[1]
state = GbuildParserState() defs["LIBO_INTERNAL_ONLY"] = None
return state return defs
exematch = GbuildParser.exepattern.match(line)
if exematch:
exename = self.exenames.get(state.target, None)
if state.cxxobjects:
self.exes.append(
GbuildExe(exematch.group(2), exename, exematch.group(1),
state.include, state.include_sys, state.defs, state.cxxobjects,
state.cxxflags, state.linked_libs))
state = GbuildParserState()
return state
if line.find('# INCLUDE :=') == 0:
isystemmatch = GbuildParser.isystempattern.findall(line)
if isystemmatch:
state.include_sys = isystemmatch
state.include = [includeswitch.strip() for includeswitch in GbuildParser.includepattern.findall(line) if
len(includeswitch) > 2]
return state
defsmatch = GbuildParser.defspattern.match(line)
if defsmatch:
alldefs = [defswitch.strip()[2:] for defswitch in defsmatch.group(1).split(' ') if len(defswitch) > 2]
for d in alldefs:
defparts = d.split('=')
if len(defparts) == 1:
defparts.append(None)
state.defs[defparts[0]] = defparts[1]
state.defs["LIBO_INTERNAL_ONLY"] = None
return state
cxxmatch = GbuildParser.cxxpattern.match(line)
if cxxmatch:
state.cxxobjects = [obj for obj in cxxmatch.group(1).split(' ') if len(obj) > 0]
return state
linkedlibsmatch = GbuildParser.linkedlibspattern.match(line)
if linkedlibsmatch:
state.linked_libs = linkedlibsmatch.group(1).strip().split(' ')
return state
ilibmatch = GbuildParser.ilibpattern.match(line)
if ilibmatch:
state.ilib = os.path.basename(ilibmatch.group(1))
return state
if line.find('# T_CXXFLAGS :=') == 0:
state.cxxflags = [cxxflag.strip() for cxxflag in GbuildParser.warningpattern.sub('', line.replace('# T_CXXFLAGS :=', '')).split(' ') if len(cxxflag) > 1]
return state
# we could match a lot of other stuff here if needed for integration rpaths etc.
return state
def _parse_hash(self, line): @staticmethod
libmatch = GbuildParser.libpattern.match(line) def __split_flags(flagsline, flagslineappend):
if libmatch: return [cxxflag.strip() for cxxflag in GbuildParser.warningpattern.sub('', '%s %s' % (flagsline, flagslineappend)).split(' ') if len(cxxflag) > 1]
return True
exematch = GbuildParser.exepattern.match(line)
if exematch:
return True
if line.find('# INCLUDE :=') == 0:
return True
defsmatch = GbuildParser.defspattern.match(line)
if defsmatch:
return True
cxxmatch = GbuildParser.cxxpattern.match(line)
if cxxmatch:
return True
linkedlibsmatch = GbuildParser.linkedlibspattern.match(line)
if linkedlibsmatch:
return True
ilibmatch = GbuildParser.ilibpattern.match(line)
if ilibmatch:
return True
if line.find('# T_CXXFLAGS :=') == 0:
return True
# we could match a lot of other stuff here if needed for integration rpaths etc.
return False
def _parse_without_hash(self, line): @staticmethod
makecmdmatch = GbuildParser.makecmdpattern.match(line) def __lib_from_json(json):
if makecmdmatch: (foundincludes, foundisystem) = GbuildParser.__split_includes(json['INCLUDE'])
self.makecmd = makecmdmatch.group(1) return GbuildLib(
# FIXME: Hack GbuildParser.libpattern.match(os.path.basename(json['MAKEFILE'])).group(1),
if self.makecmd == 'make': json['LINKTARGET'],
self.makecmd = '/usr/bin/make' os.path.dirname(json['MAKEFILE']),
return False foundincludes,
srcdirmatch = GbuildParser.srcdirpattern.match(line) foundisystem,
if srcdirmatch: GbuildParser.__split_defs(json['DEFS']),
self.srcdir = srcdirmatch.group(1) GbuildParser.__split_objs(json['CXXOBJECTS']),
return False GbuildParser.__split_flags(json['CXXFLAGS'], json['CXXFLAGSAPPEND']),
builddirmatch = GbuildParser.builddirpattern.match(line) json['LINKED_LIBS'].strip().split(' '))
if builddirmatch:
self.builddir = builddirmatch.group(1)
return False
instdirmatch = GbuildParser.instdirpattern.match(line)
if instdirmatch:
self.instdir = instdirmatch.group(1)
return False
binpathmatch = GbuildParser.binpathpattern.match(line)
if binpathmatch:
self.binpath = binpathmatch.group(1)
return False
libnamesmatch = GbuildParser.libnamespattern.match(line)
if libnamesmatch:
self.libnames = self.__mapping_to_dict(libnamesmatch.group(1))
return False
exenamesmatch = GbuildParser.exenamepattern.match(line)
if exenamesmatch:
self.exenames = self.__mapping_to_dict(exenamesmatch.group(1))
return False
rulematch = self.rulepattern.match(line)
if rulematch:
return True
def parse(self, gbuildstate): @staticmethod
workLines = [] def __exe_from_json(json):
stateActive = False (foundincludes, foundisystem) = GbuildParser.__split_includes(json['INCLUDE'])
for line in gbuildstate: return GbuildExe(
line = line.rstrip('\r\n') GbuildParser.exepattern.match(os.path.basename(json['MAKEFILE'])).group(1),
if line.startswith('#'): json['LINKTARGET'],
if self._parse_hash(line): os.path.dirname(json['MAKEFILE']),
stateActive = True foundincludes,
workLines.append(line) foundisystem,
else: GbuildParser.__split_defs(json['DEFS']),
if self._parse_without_hash(line): GbuildParser.__split_objs(json['CXXOBJECTS']),
workLines.append(line) GbuildParser.__split_flags(json['CXXFLAGS'], json['CXXFLAGSAPPEND']),
elif stateActive: json['LINKED_LIBS'].strip().split(' '))
workLines.append('!END OF STATE')
state = GbuildParserState()
for line in workLines:
if line.startswith('!END OF STATE'):
state = GbuildParserState()
continue
if line.startswith('#'):
state = self._parse_hash_old(line, state)
else:
rulematch = self.rulepattern.match(line)
if rulematch:
if len(rulematch.groups()) == 2 \
and rulematch.group(2) is not None \
and ':=' in rulematch.group(2):
# Hack to make GNU make >= 4.x happy
state = self._parse_hash_old('#' + rulematch.group(2), state)
else:
state.target = os.path.basename(rulematch.group(1))
def parse(self):
for jsonfilename in os.listdir(os.path.join(self.workdir, 'GbuildToJson', 'Library')):
with open(os.path.join(self.workdir, 'GbuildToJson', 'Library', jsonfilename), 'r') as f:
lib = self.__lib_from_json(json.load(f))
self.libnames[lib.library] = lib.name
self.libs.append(lib)
for jsonfilename in os.listdir(os.path.join(self.workdir, 'GbuildToJson', 'Executable')):
with open(os.path.join(self.workdir, 'GbuildToJson', 'Executable', jsonfilename), 'r') as f:
exe = self.__exe_from_json(json.load(f))
self.exenames[exe.executable] = exe.name
self.exes.append(exe)
for target in set(self.libs) | set(self.exes): for target in set(self.libs) | set(self.exes):
if target.location not in self.target_by_location: if target.location not in self.target_by_location:
self.target_by_location[target.location] = set() self.target_by_location[target.location] = set()
@@ -1697,9 +1580,13 @@ if __name__ == '__main__':
description='LibreOffice gbuild IDE project generator') description='LibreOffice gbuild IDE project generator')
parser.add_argument('--ide', dest='ide', required=True, parser.add_argument('--ide', dest='ide', required=True,
help='the IDE to generate project files for') help='the IDE to generate project files for')
parser.add_argument('--input', dest='input', required=False, parser.add_argument('--make', dest='makecmd', required=True,
help='the input file, not normally used, for debugging this script') help='the command to execute make')
args = parser.parse_args() args = parser.parse_args()
# FIXME: Hack
if args.makecmd == 'make':
args.makecmd = '/usr/bin/make'
paths = {} paths = {}
generators = { generators = {
'eclipsecdt': EclipseCDTIntegrationGenerator, 'eclipsecdt': EclipseCDTIntegrationGenerator,
@@ -1716,10 +1603,7 @@ if __name__ == '__main__':
print("Invalid ide. valid values are %s" % ','.join(generators.keys())) print("Invalid ide. valid values are %s" % ','.join(generators.keys()))
sys.exit(1) sys.exit(1)
if args.input: gbuildparser = GbuildParser(args.makecmd).parse()
gbuildparser = GbuildParser().parse(open(args.input, 'r'))
else:
gbuildparser = GbuildParser().parse(sys.stdin)
generators[args.ide](gbuildparser, args.ide).emit() generators[args.ide](gbuildparser, args.ide).emit()
print("Successfully created the project files.") print("Successfully created the project files.")