You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by da...@apache.org on 2020/02/02 00:30:26 UTC

[openoffice] branch scons-build created (now 1c93647)

This is an automated email from the ASF dual-hosted git repository.

damjan pushed a change to branch scons-build
in repository https://gitbox.apache.org/repos/asf/openoffice.git.


      at 1c93647  Add my gotoSCons parser/convert from gbuild to scons.

This branch includes the following new commits:

     new c128808  Initial import of a preliminary SCons-based build system. Initial port of main/fileaccess to SCons.
     new 1c93647  Add my gotoSCons parser/convert from gbuild to scons.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[openoffice] 01/02: Initial import of a preliminary SCons-based build system. Initial port of main/fileaccess to SCons.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

damjan pushed a commit to branch scons-build
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit c128808560ee319f52c4787ff923cb04bc1b5896
Author: Damjan Jovanovic <da...@apache.org>
AuthorDate: Sat Feb 1 19:40:26 2020 +0200

    Initial import of a preliminary SCons-based build system.
    Initial port of main/fileaccess to SCons.
    
    Patch by: me
---
 main/SConstruct                                    |   1 +
 main/fileaccess/{prj/makefile.mk => SConscript}    |  53 ++--
 main/fileaccess/prj/makefile.mk                    |   2 +-
 .../prj/makefile.mk => site_scons/config.py}       |  36 ++-
 .../prj/makefile.mk => site_scons/executable.py}   |  40 +--
 main/site_scons/globals.py                         | 164 ++++++++++++
 main/site_scons/platform/aooplatform.py            | 104 ++++++++
 main/site_scons/platform/freebsd.py                | 251 ++++++++++++++++++
 main/site_scons/platform/windows.py                | 293 +++++++++++++++++++++
 main/site_scons/sharedLibrary.py                   |  70 +++++
 main/site_scons/sharedObjects.py                   |  63 +++++
 main/site_scons/site_init.py                       | 149 +++++++++++
 12 files changed, 1166 insertions(+), 60 deletions(-)

diff --git a/main/SConstruct b/main/SConstruct
new file mode 100644
index 0000000..05d09bd
--- /dev/null
+++ b/main/SConstruct
@@ -0,0 +1 @@
+SConscript('fileaccess/SConscript', variant_dir=WORKDIR+'/scons/fileaccess', duplicate=0)
diff --git a/main/fileaccess/prj/makefile.mk b/main/fileaccess/SConscript
similarity index 61%
copy from main/fileaccess/prj/makefile.mk
copy to main/fileaccess/SConscript
index 353f9e0..cd47d9c 100644
--- a/main/fileaccess/prj/makefile.mk
+++ b/main/fileaccess/SConscript
@@ -19,26 +19,37 @@
 #  
 #**************************************************************
 
+objs = AOOSharedObjects()
+objs.AddAPI([
+    'offapi',
+    'udkapi'
+])
+objs.AddInclude([
+    'inc'
+])
+objs.AddDefs([
+    'FILEACCESS_DLLIMPLEMENTATION'
+])
+objs.AddCxxExceptionSources([
+    'source/FileAccess.cxx'
+])
+fileacc = AOOSharedLibrary(
+    'fileacc',
+    'OOOLIBS',
+    objs.objects
+)
+fileacc.AddLinkedLibs(
+    [
+        CPPULIB,
+        CPPUHELPERLIB,
+        SALLIB,
+        TOOLSLIB,
+        UCBHELPERLIB,
+        UNOTOOLSLIB
+    ] + STDLIBS
+)
+fileacc.SetComponentFile('util/fileacc')
+fileacc.InstallTo('${OUTDIR}/lib')
 
+Install('${OUTDIR}/xml', 'source/fileacc.xml')
 
-PRJ=..
-TARGET=prj
-
-.INCLUDE : settings.mk
-
-.IF "$(VERBOSE)"!=""
-VERBOSEFLAG :=
-.ELSE
-VERBOSEFLAG := -s
-.ENDIF
-
-.IF "$(DEBUG)"!=""
-DEBUG_ARGUMENT=DEBUG=$(DEBUG)
-.ELIF "$(debug)"!=""
-DEBUG_ARGUMENT=debug=$(debug)
-.ELSE
-DEBUG_ARGUMENT=
-.ENDIF
-
-all:
-	cd $(PRJ) && $(GNUMAKE) $(VERBOSEFLAG) -r -j$(MAXPROCESS) $(gb_MAKETARGET) $(DEBUG_ARGUMENT) && $(GNUMAKE) $(VERBOSEFLAG) -r deliverlog
diff --git a/main/fileaccess/prj/makefile.mk b/main/fileaccess/prj/makefile.mk
index 353f9e0..9476456 100644
--- a/main/fileaccess/prj/makefile.mk
+++ b/main/fileaccess/prj/makefile.mk
@@ -41,4 +41,4 @@ DEBUG_ARGUMENT=
 .ENDIF
 
 all:
-	cd $(PRJ) && $(GNUMAKE) $(VERBOSEFLAG) -r -j$(MAXPROCESS) $(gb_MAKETARGET) $(DEBUG_ARGUMENT) && $(GNUMAKE) $(VERBOSEFLAG) -r deliverlog
+	cd $(PRJ) && scons -u $(VERBOSEFLAG) -j$(MAXPROCESS) install
diff --git a/main/fileaccess/prj/makefile.mk b/main/site_scons/config.py
similarity index 60%
copy from main/fileaccess/prj/makefile.mk
copy to main/site_scons/config.py
index 353f9e0..d7f5455 100644
--- a/main/fileaccess/prj/makefile.mk
+++ b/main/site_scons/config.py
@@ -19,26 +19,24 @@
 #  
 #**************************************************************
 
+import os
 
+_siteDir, _myFilename = os.path.split(os.path.abspath(__file__))
+_mainDir, _siteDir2 = os.path.split(_siteDir)
 
-PRJ=..
-TARGET=prj
+# Or should we patch set_soenv to generate us a .py file?
+def _loadJavaProperties(filepath):
+    props = {}
+    with open(filepath, "rt") as f:
+        for line in f:
+            l = line.strip()
+            if l and not l.startswith('#'):
+                eq = l.find('=')
+                if eq >= 0:
+                    key = l[:eq].strip()
+                    value = l[(eq+1):].strip()
+                    props[key] = value
+    return props
 
-.INCLUDE : settings.mk
+soenv = _loadJavaProperties(_mainDir + '/ant.properties')
 
-.IF "$(VERBOSE)"!=""
-VERBOSEFLAG :=
-.ELSE
-VERBOSEFLAG := -s
-.ENDIF
-
-.IF "$(DEBUG)"!=""
-DEBUG_ARGUMENT=DEBUG=$(DEBUG)
-.ELIF "$(debug)"!=""
-DEBUG_ARGUMENT=debug=$(debug)
-.ELSE
-DEBUG_ARGUMENT=
-.ENDIF
-
-all:
-	cd $(PRJ) && $(GNUMAKE) $(VERBOSEFLAG) -r -j$(MAXPROCESS) $(gb_MAKETARGET) $(DEBUG_ARGUMENT) && $(GNUMAKE) $(VERBOSEFLAG) -r deliverlog
diff --git a/main/fileaccess/prj/makefile.mk b/main/site_scons/executable.py
similarity index 52%
copy from main/fileaccess/prj/makefile.mk
copy to main/site_scons/executable.py
index 353f9e0..fb602ae 100644
--- a/main/fileaccess/prj/makefile.mk
+++ b/main/site_scons/executable.py
@@ -19,26 +19,28 @@
 #  
 #**************************************************************
 
+from SCons.Script import *
+from config import soenv
+from globals import *
 
+class AOOExecutable:
+    def __init__(self, target, group, objects):
+        self.env = DefaultEnvironment().Clone()
+        self.exe = self.env.Program(
+            target,
+            source = objects
+        )
+        self.env['AOO_THIS'] = self.exe[0]
+        self.env.Append(LINKFLAGS=platform.getExecutableLDFlags(soenv, group, OUTDIRLOCATION, DEBUGGING, DEBUGLEVEL))
+        self.env.Append(LIBPATH=platform.getLDPATH(soenv))
+        self.env['AOO_GROUP'] = group
+        self.env['AOO_LAYER'] = platform.getLibraryGroupLayer(group)
 
-PRJ=..
-TARGET=prj
+    def AddLinkedLibs(self, libs):
+        self.env.Append(LIBS=libs)
 
-.INCLUDE : settings.mk
+    def SetTargetTypeGUI(self, isGUI):
+        self.env.Append(LINKFLAGS=platform.getTargetTypeGUIFlags(isGUI))
 
-.IF "$(VERBOSE)"!=""
-VERBOSEFLAG :=
-.ELSE
-VERBOSEFLAG := -s
-.ENDIF
-
-.IF "$(DEBUG)"!=""
-DEBUG_ARGUMENT=DEBUG=$(DEBUG)
-.ELIF "$(debug)"!=""
-DEBUG_ARGUMENT=debug=$(debug)
-.ELSE
-DEBUG_ARGUMENT=
-.ENDIF
-
-all:
-	cd $(PRJ) && $(GNUMAKE) $(VERBOSEFLAG) -r -j$(MAXPROCESS) $(gb_MAKETARGET) $(DEBUG_ARGUMENT) && $(GNUMAKE) $(VERBOSEFLAG) -r deliverlog
+    def InstallTo(self, path):
+        self.env.Install(path, self.exe)
diff --git a/main/site_scons/globals.py b/main/site_scons/globals.py
new file mode 100644
index 0000000..8a65f17
--- /dev/null
+++ b/main/site_scons/globals.py
@@ -0,0 +1,164 @@
+#**************************************************************
+#  
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#    http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#  
+#**************************************************************
+
+from config import soenv
+import os
+_siteDir, _myFilename = os.path.split(os.path.abspath(__file__))
+import sys
+sys.path.insert(0, _siteDir + '/platform')
+
+############################
+# Platforms
+############################
+
+if soenv['OS'] == 'FREEBSD':
+    from freebsd import *
+    platform = FreeBSD()
+elif soenv['OS'] == 'WNT':
+    from windows import *
+    platform = Windows()
+else:
+    raise Exception ('Unsupported OS: ' + soenv['OS'])
+
+GUI = platform.getGUI()
+COMID = platform.getCOMID()
+
+############################
+# Product and debug settings
+############################
+
+PRODUCT = (soenv.get('PRODUCT') == 'TRUE')
+
+if 'DEBUG' in soenv:
+    DEBUGLEVEL = 2
+elif PRODUCT:
+    DEBUGLEVEL = 1
+else:
+    DEBUGLEVEL = 0
+
+DEBUGGING = False
+if DEBUGLEVEL == 2:
+    DEBUGGING = True
+
+if soenv.get('ENABLE_SYMBOLS') == 'SMALL':
+    DEBUGGING = True
+elif soenv.get('ENABLE_SYMBOLS') == 'TRUE':
+    DEBUGGING = True
+
+if soenv.get('ENABLE_CRASHDUMP') == 'TRUE':
+    DEBUGGING = True
+
+
+############################
+# Precompiled headers
+############################
+
+ENABLE_PCH = (soenv.get('ENABLE_PCH') == 'TRUE')
+
+############################
+# Defs
+############################
+
+GLOBALDEFS = [
+    '_REENTRANT',
+    'CUI',
+    'ENABLE_LAYOUT_EXPERIMENTAL=0',
+    'ENABLE_LAYOUT=0',
+    'OSL_DEBUG_LEVEL=' + str(DEBUGLEVEL),
+    'SOLAR_JAVA',
+    'SUPD=' + soenv['UPD'],
+    'VCL'
+]
+
+GLOBALDEFS += platform.getOSDefs(soenv)
+GLOBALDEFS += platform.getCompilerDefs(soenv)
+GLOBALDEFS += platform.getCPUDefs(soenv)
+
+if PRODUCT:
+    GLOBALDEFS += ['PRODUCT', 'PRODUCT_FULL']
+else:
+    GLOBALDEFS += ['DBG_UTIL', 'STLP_DEBUG']
+
+if DEBUGLEVEL == 2:
+    GLOBALDEFS += ['DEBUG'];
+else:
+    GLOBALDEFS += ['OPTIMIZE', 'NDEBUG']
+
+if 'ENABLE_GTK' in soenv:
+    GLOBALDEFS += ['ENABLE_GTK']
+if 'ENABLE_KDE' in soenv:
+    GLOBALDEFS += ['ENABLE_KDE']
+if 'ENABLE_KDE4' in soenv:
+    GLOBALDEFS += ['ENABLE_KDE4']
+if 'ENABLE_GRAPHITE' in soenv:
+    GLOBALDEFS += ['ENABLE_GRAPHITE']
+
+############################
+# Paths
+############################
+
+OUTDIR = soenv['SOLARVERSION'] + "/" + soenv['INPATH']
+WORKDIR = OUTDIR + "/workdir"
+OUTDIRLOCATION = OUTDIR + os.sep + 'lib'
+
+############################
+# Libraries
+############################
+
+# FIXME: this probably belongs elsewhere
+UCBHELPER_MAJOR=4
+UDK_MAJOR=3
+
+if GUI == 'UNX' or soenv['COM'] == 'GCC':
+    if GUI+soenv['COM'] == 'WNTGCC':
+        CPPULIB = 'cppu' + UDK_MAJOR
+        CPPUHELPERLIB = 'cppuhelper' + UDK_MAJOR + COMID
+    elif GUI == 'OS2':
+        CPPULIB = 'cppu' + UDK_MAJOR
+        CPPUHELPERLIB = 'cppuh' + UDK_MAJOR
+    else:
+        CPPULIB = 'uno_cppu'
+        CPPUHELPERLIB = 'uno_cppuhelper' + COMID
+
+    if GUI+soenv['COM'] == 'WNTGCC' or GUI == 'OS2':
+        SALLIB = 'sal' + UDK_MAJOR
+    else:
+        SALLIB = 'uno_sal'
+
+    TOOLSLIB = 'tl'
+
+    if GUI == 'OS2':
+        UCBHELPERLIB = 'ucbh' + UCBHELPER_MAJOR
+    else:
+        UCBHELPERLIB=  'ucbhelper' + COMID
+ 
+    UNOTOOLSLIB = 'utl'
+ 
+else:
+    CPPULIB = 'icppu'
+    CPPUHELPERLIB = 'icppuhelper'
+    SALLIB = 'isal'
+    TOOLSLIB = 'itools'
+    UCBHELPERLIB = 'iucbhelper'
+    UNOTOOLSLIB = 'iutl'
+
+STDLIBS = platform.getStandardLibs()
+
diff --git a/main/site_scons/platform/aooplatform.py b/main/site_scons/platform/aooplatform.py
new file mode 100644
index 0000000..11dfbb0
--- /dev/null
+++ b/main/site_scons/platform/aooplatform.py
@@ -0,0 +1,104 @@
+#**************************************************************
+#  
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#    http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#  
+#**************************************************************
+
+from abc import ABC, abstractmethod
+
+class Platform(ABC):
+    @abstractmethod
+    def getGUI(self):
+        pass
+
+    @abstractmethod
+    def getCOMID(self):
+        pass
+
+    @abstractmethod
+    def getCompilerDefs(self, soenv):
+        pass
+
+    @abstractmethod
+    def getCPUDefs(self, soenv):
+        pass
+
+    @abstractmethod
+    def getOSDefs(self, soenv):
+        pass
+
+    @abstractmethod
+    def getLibraryDefs(self, soenv):
+        pass
+
+    @abstractmethod
+    def getCFlags(self, soenv):
+        pass
+
+    @abstractmethod
+    def getCXXFlags(self, soenv):
+        pass
+
+    @abstractmethod
+    def getInclude(self, soenv):
+        pass
+
+    @abstractmethod
+    def getIncludeStl(self, soenv):
+        pass
+
+    @abstractmethod
+    def getExceptionFlags(self, soenv, enabled):
+        pass
+
+    @abstractmethod
+    def getCompilerOptFlags(self, enabled, debugLevel):
+        pass
+
+    @abstractmethod
+    def getDebugCFlags(self, compiler, enableSymbols):
+        pass
+
+    @abstractmethod
+    def getExecutableLDFlags(self, soenv, group, outDirLocation, debugging, debugLevel):
+        pass
+    
+    @abstractmethod
+    def getLibraryLDFlags(self, soenv, group, outDirLocation, debugging, debugLevel):
+        pass
+
+    @abstractmethod
+    def getStandardLibs(self):
+        pass
+
+    @abstractmethod
+    def getLibraryGroupLayer(self, group):
+        pass
+
+    @abstractmethod
+    def getLibraryLayerComponentPrefix(self, layer):
+        pass
+
+    @abstractmethod
+    def getExecutableEnvironment(self, soenv):
+        pass
+
+    @abstractmethod
+    def getTargetTypeGUIFlags(self, isGUI):
+        pass
+
diff --git a/main/site_scons/platform/freebsd.py b/main/site_scons/platform/freebsd.py
new file mode 100644
index 0000000..c1e845f
--- /dev/null
+++ b/main/site_scons/platform/freebsd.py
@@ -0,0 +1,251 @@
+#**************************************************************
+#  
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#    http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#  
+#**************************************************************
+
+import subprocess
+import aooplatform
+
+class FreeBSD(aooplatform.Platform):
+    def __init__(self):
+        self.GXX_INCLUDE_PATH = None
+        self.executableGroupLayers = {}
+        self.executableGroupLayers['UREBIN'] = 'UREBIN'
+        self.executableGroupLayers['SDK'] = 'SDKBIN'
+        self.executableGroupLayers['OOO'] = 'OOO'
+        self.executableGroupLayers['BRAND'] = 'BRAND'
+        self.executableGroupLayers['NONE'] = 'NONEBIN'
+        self.libraryGroupLayers = {}
+        self.libraryGroupLayers['OOOLIBS'] = 'OOO'
+        self.libraryGroupLayers['PLAINLIBS_URE'] = 'URELIB'
+        self.libraryGroupLayers['PLAINLIBS_OOO'] = 'OOO'
+        self.libraryGroupLayers['RTLIBS'] = 'OOO'
+        self.libraryGroupLayers['RTVERLIBS'] = 'URELIB'
+        self.libraryGroupLayers['STLLIBS'] = 'URELIB'
+        self.libraryGroupLayers['UNOLIBS_URE'] = 'URELIB'
+        self.libraryGroupLayers['UNOLIBS_OOO'] = 'OOO'
+        self.libraryGroupLayers['UNOVERLIBS'] = 'URELIB'
+        self.layerRPaths = {}
+        self.layerRPaths['URELIB'] = '$ORIGIN'
+        self.layerRPaths['UREBIN'] = '$ORIGIN/../lib:$ORIGIN'
+        self.layerRPaths['OOO'] = '$ORIGIN:$ORIGIN/../ure-link/lib'
+        self.layerRPaths['BRAND'] = '$ORIGIN:$ORIGIN/../basis-link/program:$ORIGIN/../basis-link/ure-link/lib'
+        self.layerRPaths['SDKBIN'] = '$ORIGIN/../../ure-link/lib'
+        self.layerRPaths['NONEBIN'] = '$ORIGIN/../lib:$ORIGIN'
+        self.layerComponentPrefixes = {}
+        self.layerComponentPrefixes['OOO'] = 'vnd.sun.star.expand:\\$$OOO_BASE_DIR/program/'
+        self.layerComponentPrefixes['URELIB'] = 'vnd.sun.star.expand:\\$$URE_INTERNAL_LIB_DIR/'
+        self.layerComponentPrefixes['NONE'] = 'vnd.sun.star.expand:\\$$OOO_INBUILD_SHAREDLIB_DIR/'
+
+    def getGUI(self):
+        return 'UNX'
+
+    def getCOMID(self):
+        return 'gcc3'
+
+    def getCompilerDefs(self, soenv):
+        if self.GXX_INCLUDE_PATH is None:
+            gccVersion = subprocess.Popen("gcc -dumpversion", shell=True, stdout=subprocess.PIPE).stdout.readline().rstrip()
+            self.GXX_INCLUDE_PATH = soenv['COMPATH'] + "/include/c++/" + gccVersion.decode('utf-8')
+        return [
+            soenv['COM'],
+            'HAVE_GCC_VISIBILITY_FEATURE',
+            'CPPU_ENV=gcc3',
+            'GXX_INCLUDE_PATH=' + self.GXX_INCLUDE_PATH
+        ]
+
+    def getCPUDefs(self, soenv):
+        return [soenv['CPUNAME']]
+
+    def getOSDefs(self, soenv):
+        defs = [
+            soenv['OS'],
+            '_PTHREADS',
+            'UNIX',
+            'UNX'
+        ]
+        if 'PTHREAD_CFLAGS' in soenv:
+            defs += [soenv['PTHREAD_CFLAGS']]
+        return defs
+
+    def getCFlags(self, soenv):
+        flags = [
+            '-Wall',
+            '-Wendif-labels',
+            '-Wextra',
+            '-Wshadow',
+            '-fPIC',
+            '-fmessage-length=0',
+            '-fno-common',
+            '-fno-strict-aliasing',
+            '-fvisibility=hidden',
+            '-pipe'
+        ]
+        if soenv.get('EXTERNAL_WARNINGS_NOT_ERRORS') != 'TRUE':
+            flags += ['-Werror']
+        if 'SYSBASE' in soenv:
+            flags += ['--sysroot=' + soenv['SYSBASE']]
+        return flags
+
+    def getCXXFlags(self, soenv):
+        flags = [
+            '-Wall',
+            '-Wendif-labels',
+            '-Wextra',
+            '-Wno-ctor-dtor-privacy',
+            '-Wno-non-virtual-dtor',
+            '-Wshadow',
+            '-fPIC',
+            '-fmessage-length=0',
+            '-fno-common',
+            '-fno-strict-aliasing',
+            '-fno-use-cxa-atexit',
+            '-fvisibility-inlines-hidden',
+            '-fvisibility=hidden',
+            '-pipe'
+        ]
+        if soenv['EXTERNAL_WARNINGS_NOT_ERRORS'] != 'TRUE':
+            flags += ['-Werror']
+        if 'SYSBASE' in soenv:
+            flags += ['--sysroot=' + soenv['SYSBASE']]
+        if soenv['COM'] == 'CLANG':
+            flags += ['-DHAVE_STL_INCLUDE_PATH']
+        else:
+            flags += ['-DBOOST_TR1_DISABLE_INCLUDE_NEXT', '-DBOOST_TR1_GCC_INCLUDE_PATH=c++']
+        return flags
+
+    def getInclude(self, soenv):
+        includes = []
+        for i in soenv['SOLARINC'].split(' '):
+            if i.endswith('/stl'):
+                continue;
+            if i.startswith('-I'):
+                includes.append(i[2:])
+        return includes
+
+    def getIncludeStl(self, soenv):
+        includes = []
+        for i in soenv['SOLARINC'].split(' '):
+            if i.startswith('-I') and i.endswith('/stl'):
+                includes.append(i[2:])
+        return includes
+
+    def getExceptionFlags(self, soenv, enabled):
+        flags = []
+        if enabled:
+            flags += ['-DEXCEPTIONS_ON', '-fexceptions']
+            if soenv['COM'] == 'GCC':
+                flags += ['-fno-enforce-eh-specs'];
+        else:
+            flags += ['-DEXCEPTIONS_OFF', '-fno-exceptions']
+        return flags
+
+    def getCompilerOptFlags(self, enabled, debugLevel):
+        if enabled:
+            if debugLevel == 2:
+                return ['-O0']
+            else:
+                return ['-Os']
+        else:
+            return ['-O0']
+
+    def getDebugCFlags(self, compiler, enableSymbols):
+        if compiler == 'CLANG':
+            if enableSymbols == 'SMALL':
+                return ['-ggdb1', '-fno-inline']
+            else:
+                return ['-ggdb3', '-fno-inline']
+        else:
+            if enableSymbols == 'SMALL':
+                return ['-ggdb1', '-finline-limit=0', '-fno-inline', '-fno-default-inline']
+            else:
+                return ['-ggdb3', '-finline-limit=0', '-fno-inline', '-fno-default-inline']
+
+    def getRPATH(self, layer):
+        return self.layerRPaths[layer]
+
+    def getLibraryDefs(self, soenv):
+        return []
+
+    def getLDFlags(self, soenv, debugging, debugLevel):
+        sysbase = soenv.get('SYSBASE')
+        if sysbase is None:
+            sysbase = ''
+        flags = [
+            '-Wl,-rpath-link,' + sysbase + '/lib:' + sysbase + '/usr/lib',
+            '-Wl,-z,combreloc',
+            '-Wl,-z,defs'
+        ]
+        if soenv.get('FBSD_GCC_RPATH') is not None:
+            flags += [soenv['FBSD_GCC_RPATH']]
+        if sysbase != '':
+            flags += ['-Wl,--sysroot=' + sysbase]
+        if soenv.get('HAVE_LD_HASH_STYLE') == 'TRUE':
+            flags += ['-Wl,--hash-style=both']
+        if soenv.get('HAVE_LD_BSYMBOLIC_FUNCTIONS') == 'TRUE':
+            flags += [
+                '-Wl,--dynamic-list-cpp-new',
+                '-Wl,--dynamic-list-cpp-typeinfo',
+                '-Wl,-Bsymbolic-functions'
+            ]
+        if debugLevel == 0:
+            flags += ['-Wl,-O1']
+        return flags;
+
+    def getLDPATH(self, soenv):
+        path = soenv['SOLARLIB']
+        path = path.replace('-L../lib ', '')
+        path = path.replace('-L', '')
+        return path.split()
+
+    def getExecutableLDFlags(self, soenv, group, outDirLocation, debugging, debugLevel):
+        flags = self.getLDFlags(soenv, debugging, debugLevel)
+        flags += [
+            '-Wl,-rpath,' + self.getRPATH(self.executableGroupLayers(group)),
+            '-Wl,-rpath-link,' + outDirLocation
+        ]
+        return flags
+
+    def getLibraryLDFlags(self, soenv, group, outDirLocation, debugging, debugLevel):
+        flags = self.getLDFlags(soenv, debugging, debugLevel)
+        flags += [ '-Wl,-z,noexecstack' ]
+        flags += [
+            '-Wl,-z,origin',
+            '-Wl,-rpath,' + self.getRPATH(self.getLibraryGroupLayer(group)),
+            '-Wl,-rpath-link,' + outDirLocation
+        ]
+        return flags
+
+    def getStandardLibs(self):
+        return []
+
+    def getLibraryGroupLayer(self, group):
+        return self.libraryGroupLayers[group]
+
+    def getLibraryLayerComponentPrefix(self, layer):
+        return self.layerComponentPrefixes[layer]
+
+    def getExecutableEnvironment(self, soenv):
+        return {
+            'LD_LIBRARY_PATH' : soenv['OUTDIR'] + '/lib'
+        }
+    
+    def getTargetTypeGUIFlags(self, isGUI):
+        return []
+
diff --git a/main/site_scons/platform/windows.py b/main/site_scons/platform/windows.py
new file mode 100644
index 0000000..eeec1ad
--- /dev/null
+++ b/main/site_scons/platform/windows.py
@@ -0,0 +1,293 @@
+#**************************************************************
+#  
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#    http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#  
+#**************************************************************
+
+import aooplatform
+
+class Windows(aooplatform.Platform):
+    def __init__(self):
+        self.libraryGroupLayers = {}
+        self.libraryGroupLayers['OOOLIBS'] = 'OOO'
+        self.libraryGroupLayers['PLAINLIBS_URE'] = 'OOO'
+        self.libraryGroupLayers['PLAINLIBS_OOO'] = 'OOO'
+        self.libraryGroupLayers['RTLIBS'] = 'OOO'
+        self.libraryGroupLayers['RTVERLIBS'] = 'OOO'
+        self.libraryGroupLayers['STLLIBS'] = 'OOO'
+        self.libraryGroupLayers['UNOLIBS_URE'] = 'OOO'
+        self.libraryGroupLayers['UNOLIBS_OOO'] = 'OOO'
+        self.libraryGroupLayers['UNOVERLIBS'] = 'OOO'
+        self.layerComponentPrefixes = {}
+        self.layerComponentPrefixes['OOO'] = 'vnd.sun.star.expand:$$OOO_BASE_DIR/program/'
+        self.layerComponentPrefixes['URELIB'] = 'vnd.sun.star.expand:$$URE_INTERNAL_LIB_DIR/'
+        self.layerComponentPrefixes['NONE'] = 'vnd.sun.star.expand:$$OOO_INBUILD_SHAREDLIB_DIR/'
+
+    def getGUI(self):
+        return 'WNT'
+
+    def getCOMID(self):
+        return 'MSC'
+
+    def getCompilerDefs(self, soenv):
+        defs = [
+            'MSC',
+            '_CRT_NON_CONFORMING_SWPRINTFS',
+            '_CRT_NONSTDC_NO_DEPRECATE',
+            '_CRT_SECURE_NO_DEPRECATE',
+            '_MT',
+            '_DLL',
+            'CPPU_ENV=' + soenv['COMNAME'],
+            'FULL_DESK',
+            'M1500'
+        ]
+        if soenv['CPUNAME'] == 'INTEL':
+            defs += ['BOOST_MEM_FN_ENABLE_CDECL']
+        return defs;
+
+    def getCPUDefs(self, soenv):
+        defs = [
+            'ALIGN=' + soenv['ALIGN'],
+            'CPUNAME=' + soenv['CPUNAME']
+        ]
+        if soenv['CPUNAME'] == 'INTEL':
+            defs += ['_X86_=1']
+        elif soenv['CPUNAME'] == 'X86_64':
+            defs += ['_AMD64_=1']
+        return defs
+
+    def getOSDefs(self, soenv):
+        return [
+            'WINVER=0x0500',
+            '_WIN32_IE=0x0500',
+            'NT351',
+            'WIN32',
+            'WNT'
+        ]
+
+    def getCFlags(self, soenv):
+        flags = [
+            '-Gd',
+            '-GR',
+            '-Gs',
+            '-GS',
+            '-nologo',
+            '-Wall',
+            '-wd4005',
+            '-wd4061',
+            '-wd4127',
+            '-wd4180',
+            '-wd4189',
+            '-wd4191',
+            '-wd4217',
+            '-wd4250',
+            '-wd4251',
+            '-wd4255',
+            '-wd4275',
+            '-wd4290',
+            '-wd4294',
+            '-wd4350',
+            '-wd4355',
+            '-wd4365',
+            '-wd4503',
+            '-wd4505',
+            '-wd4511',
+            '-wd4512',
+            '-wd4514',
+            '-wd4611',
+            '-wd4619',
+            '-wd4625',
+            '-wd4626',
+            '-wd4640',
+            '-wd4668',
+            '-wd4675',
+            '-wd4692',
+            '-wd4710',
+            '-wd4711',
+            '-wd4738',
+            '-wd4786',
+            '-wd4800',
+            '-wd4820',
+            '-wd4826',
+            '-Zc:wchar_t-',
+            '-Zm500'
+        ]
+        if soenv['EXTERNAL_WARNINGS_NOT_ERRORS'] != 'TRUE':
+            flags += ['-WX']
+        return flags
+
+    def getCXXFlags(self, soenv):
+        flags = [
+            '-Gd',
+            '-GR',
+            '-Gs',
+            '-GS',
+            '-Gy',
+            '-nologo',
+            '-Wall',
+            '-wd4005',
+            '-wd4061',
+            '-wd4127',
+            '-wd4180',
+            '-wd4189',
+            '-wd4191',
+            '-wd4217',
+            '-wd4250',
+            '-wd4251',
+            '-wd4275',
+            '-wd4290',
+            '-wd4294',
+            '-wd4350',
+            '-wd4355',
+            '-wd4365',
+            '-wd4503',
+            '-wd4505',
+            '-wd4511',
+            '-wd4512',
+            '-wd4514',
+            '-wd4611',
+            '-wd4619',
+            '-wd4625',
+            '-wd4626',
+            '-wd4640',
+            '-wd4668',
+            '-wd4675',
+            '-wd4692',
+            '-wd4710',
+            '-wd4711',
+            '-wd4738',
+            '-wd4786',
+            '-wd4800',
+            '-wd4820',
+            '-wd4826',
+            '-Zc:wchar_t-',
+            '-Zm500'
+        ]
+        if soenv['EXTERNAL_WARNINGS_NOT_ERRORS'] != 'TRUE':
+            flags += ['-WX']
+        return flags
+
+    def getInclude(self, soenv):
+        includes = []
+        for i in soenv['SOLARINC'].split(' '):
+            if i.endswith('/stl'):
+                continue;
+            if i.startswith('-I'):
+                includes.append(i[2:])
+        return includes
+
+    def getIncludeStl(self, soenv):
+        includes = []
+        for i in soenv['SOLARINC'].split(' '):
+            if i.startswith('-I') and i.endswith('/stl'):
+                includes.append(i[2:])
+        return includes
+
+    def getExceptionFlags(self, soenv, enabled):
+        flags = []
+        if enabled:
+            flags += ['-DEXCEPTIONS_ON', '-EHa']
+        else:
+            flags += ['-DEXCEPTIONS_OFF']
+        return flags
+
+    def getCompilerOptFlags(self, enabled, debugLevel):
+        if enabled:
+            if debugLevel == 2:
+                return []
+            else:
+                return ['-Ob1', '-Oxs', '-Oy-']
+        else:
+            return ['-Od']
+
+    def getDebugCFlags(self, compiler, debugging, enableSymbols):
+        return ['-Zi']
+
+    def getLibraryDefs(self, soenv):
+        return ['_DLL_']
+
+    def getLDFlags(self, soenv, debugging, debugLevel):
+        flags = [
+            '-NODEFAULTLIB'
+        ]
+        if soenv['CPUNAME'] == 'INTEL':
+            flags += ['-MACHINE:IX86']
+        elif soenv['CPUNAME'] == 'X86_64':
+            flags += ['-MACHINE:X64']
+        if debugging:
+            flags += ['-DEBUG']
+        return flags;
+
+    def getLDPATH(self, soenv):
+        path = []
+        ilib = soenv['ILIB']
+        ilib = ilib.replace(';', ' ')
+        for i in ilib.split(' '):
+            if i != '.':
+                path += [i]
+        return path
+
+    def getExecutableLDFlags(self, soenv, group, outDirLocation, debugging, debugLevel):
+        flags = self.getLDFlags(soenv, debugging, debugLevel)
+        flags += [
+            '-RELEASE',
+            '-BASE:0x1b000000',
+            '-OPT:NOREF',
+            '-INCREMENTAL:NO',
+            '-DEBUG',
+            '-NXCOMPAT',
+            '-DYNAMICBASE'
+        ]
+        if env['CPUNAME'] == 'INTEL':
+            flags += ['-SAFESEH']
+        return flags
+
+    def getLibraryLDFlags(self, soenv, group, outDirLocation, debugging, debugLevel):
+        flags = self.getLDFlags(soenv, debugging, debugLevel)
+        flags += [
+            '-DLL',
+            '-OPT:NOREF',
+            '-NXCOMPAT',
+            '-DYNAMICBASE',
+        ]
+        if env['CPUNAME'] == 'INTEL':
+            flags += ['-SAFESEH']
+        return flags
+
+    def getStandardLibs(self):
+        return [
+            'kernel32',
+            'msvcrt',
+            'oldnames',
+            'uwinapi'
+        ]
+
+    def getLibraryGroupLayer(self, group):
+        return self.libraryGroupLayers[group]
+
+    def getLibraryLayerComponentPrefix(self, layer):
+        return self.layerComponentPrefixes[layer]
+
+    def getExecutableEnvironment(self, soenv):
+        return {}
+
+    def getTargetTypeGUIFlags(self, isGUI):
+        if isGUI:
+            return '-SUBSYSTEM:WINDOWS'
+        else:
+            return '-SUBSYSTEM:CONSOLE'
diff --git a/main/site_scons/sharedLibrary.py b/main/site_scons/sharedLibrary.py
new file mode 100644
index 0000000..afe7644
--- /dev/null
+++ b/main/site_scons/sharedLibrary.py
@@ -0,0 +1,70 @@
+#**************************************************************
+#  
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#    http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#  
+#**************************************************************
+
+from SCons.Script import *
+from config import soenv
+from globals import *
+
+class AOOSharedLibrary:
+    def __init__(self, target, group, sharedObjects):
+        self.env = DefaultEnvironment().Clone()
+        self.sharedLib = self.env.SharedLibrary(
+            target,
+            source = sharedObjects
+        )
+        self.env['AOO_THIS'] = self.sharedLib[0]
+        self.env.Append(LINKFLAGS=platform.getLibraryLDFlags(soenv, group, OUTDIRLOCATION, DEBUGGING, DEBUGLEVEL))
+        self.env.Append(LIBPATH=platform.getLDPATH(soenv))
+        self.env['AOO_GROUP'] = group
+        self.env['AOO_LAYER'] = platform.getLibraryGroupLayer(group)
+
+    def AddLinkedLibs(self, libs):
+        self.env.Append(LIBS=libs)
+
+    def SetComponentFile(self, path):
+        componentFile = File(path + '.component')
+        inbuildComponentFile = File(path + '.inbuild.component')
+
+        outdirComponentDir = Dir(OUTDIR + '/xml/component/' + componentFile.srcnode().dir.path)
+
+        xsltenv = self.env.Clone()
+        xsltenv.Append(ENV = platform.getExecutableEnvironment(soenv))
+        if soenv['SYSTEM_LIBXSLT'] == 'YES':
+            xsltenv['AOO_XSLTPROC'] = 'xsltproc'
+        else:
+            xsltenv['AOO_XSLTPROC'] = '${OUTDIR}/bin/xsltproc'
+        xsltenv['AOO_COMPONENTPREFIX'] = platform.getLibraryLayerComponentPrefix(self.env['AOO_LAYER'])
+        xsltenv['AOO_INBUILDCOMPONENTPREFIX'] = platform.getLibraryLayerComponentPrefix('NONE')
+
+        finalComponent = xsltenv.Command(componentFile, componentFile.srcnode(),
+            '${AOO_XSLTPROC} --nonet --stringparam uri "${AOO_COMPONENTPREFIX}${AOO_THIS.name}"' \
+            ' -o $TARGET ${SOLARENV}/bin/createcomponent.xslt $SOURCE'
+        )
+        inbuildComponent = xsltenv.Command(inbuildComponentFile, componentFile.srcnode(),
+            '${AOO_XSLTPROC} --nonet --stringparam uri "${AOO_INBUILDCOMPONENTPREFIX}${AOO_THIS.name}"' \
+            ' -o $TARGET ${SOLARENV}/bin/createcomponent.xslt $SOURCE'
+        )
+
+        self.env.Install(outdirComponentDir, finalComponent)
+        self.env.Install(outdirComponentDir, inbuildComponent)
+
+    def InstallTo(self, path):
+        self.env.Install(path, self.sharedLib)
diff --git a/main/site_scons/sharedObjects.py b/main/site_scons/sharedObjects.py
new file mode 100644
index 0000000..0d068b5
--- /dev/null
+++ b/main/site_scons/sharedObjects.py
@@ -0,0 +1,63 @@
+#**************************************************************
+#  
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#    http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#  
+#**************************************************************
+
+from SCons.Script import *
+from config import soenv
+from globals import *
+
+class AOOSharedObjects:
+    def __init__(self):
+        self.env = DefaultEnvironment().Clone()
+        self.env.Append(CPPDEFINES=platform.getLibraryDefs(soenv))
+        if DEBUGGING:
+            self.env.Append(CFLAGS=platform.getDebugCFlags(soenv['COM'], soenv['ENABLE_SYMBOLS']))
+            self.env.Append(CXXFLAGS=platform.getDebugCFlags(soenv['COM'], soenv['ENABLE_SYMBOLS']))
+        self.objects = []
+
+    def AddDefs(self, defs):
+        self.env.Append(CPPDEFINES=defs)
+
+    def AddInclude(self, includes):
+        self.env.Append(CPPPATH=includes)
+
+    def AddAPI(self, names):
+        for name in names:
+            self.env.Append(CPPPATH='${OUTDIR}/inc/' + name)
+
+    def AddCxxExceptionSources(self, names):
+        self.AddCxxSources(names,
+            platform.getExceptionFlags(soenv, True)
+            + platform.getCompilerOptFlags(DEBUGLEVEL < 2, DEBUGLEVEL))
+
+    def AddCxxNoExceptionSources(self, names):
+        self.AddCxxSources(names,
+            platform.getExceptionFlags(soenv, False)
+            + platform.getCompilerOptFlags(DEBUGLEVEL < 2, DEBUGLEVEL))
+
+    def AddCxxSources(self, names, flags):
+        for name in names:
+            self.objects.append(
+                self.env.SharedObject(
+                    name,
+                    CXXFLAGS = self.env['CXXFLAGS'] + flags
+               )
+           )
+
diff --git a/main/site_scons/site_init.py b/main/site_scons/site_init.py
new file mode 100644
index 0000000..f41a204
--- /dev/null
+++ b/main/site_scons/site_init.py
@@ -0,0 +1,149 @@
+#**************************************************************
+#  
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#    http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#  
+#**************************************************************
+
+from SCons.Script import *
+import sys
+import os
+from config import soenv
+import component
+from globals import *
+
+
+###########################
+# Envirionment
+###########################
+
+env = DefaultEnvironment(
+    CC = soenv['CC'],
+    CXX = soenv['CXX'],
+    CPPPATH = platform.getInclude(soenv)
+)
+env.Append(CPPDEFINES = GLOBALDEFS)
+env.Append(CFLAGS = platform.getCFlags(soenv))
+env.Append(CXXFLAGS = platform.getCFlags(soenv))
+
+## Add some common paths to the SCons environment
+
+env['OUTDIR'] = soenv['OUTDIR']
+env['WORKDIR'] = soenv['WORKDIR']
+env['SOLARENV'] = soenv['SOLARENV']
+
+###########################
+# API
+###########################
+
+from sharedLibrary import AOOSharedLibrary
+from sharedObjects import AOOSharedObjects
+
+def CreateSharedLibraryEnvironment(name, group):
+    env = Environment()
+    env.Replace(CC=soenv['CC'])
+    env.Replace(CXX=soenv['CXX'])
+
+    env.Append(CPPPATH=platform.getInclude(soenv))
+
+    defines = GLOBALDEFS
+    defines += platform.getLibraryDefs(soenv)
+    env.Append(CPPDEFINES=defines)
+
+    cflags = platform.getCFlags(soenv)
+    cxxflags = platform.getCXXFlags(soenv)
+    if DEBUGGING:
+        cflags += platform.getDebugCFlags(soenv['COM'], soenv['ENABLE_SYMBOLS'])
+        cxxflags += platform.getDebugCFlags(soenv['COM'], soenv['ENABLE_SYMBOLS'])
+    env.Append(CFLAGS=cflags)
+    print("APPENDING " + str(cxxflags))
+    env.Replace(CXXFLAGS=cxxflags)
+    print("CXXFLAGS is " + str(env['CXXFLAGS']))
+
+    env.Append(LINKFLAGS=platform.getLibraryLDFlags(soenv, group, OUTDIRLOCATION, DEBUGGING, DEBUGLEVEL))
+    env.Append(LIBPATH=platform.getLDPATH(soenv))
+
+    env['SOLARENV'] = soenv['SOLARENV']
+    env['AOO_GROUP'] = group
+    env['AOO_LAYER'] = platform.getLibraryGroupLayer(group)
+    env['AOO_COMPONENTPREFIX'] = platform.getLibraryLayerComponentPrefix(env['AOO_LAYER'])
+
+    env.AddMethod(AddAPI)
+    env.AddMethod(AddExceptionSharedObjects)
+    env.AddMethod(AddNoExceptionSharedObjects)
+    env.AddMethod(AddCxxSharedObjects)
+    env.AddMethod(SetComponentFile)
+
+    return env
+
+def AddAPI(env, names):
+    for name in names:
+        env.Append(CPPPATH=OUTDIR + '/inc/' + name)
+
+def AddExceptionSharedObjects(env, names):
+    return AddCxxSharedObjects(env, names,
+        platform.getExceptionFlags(soenv, True)
+        + platform.getCompilerOptFlags(DEBUGLEVEL < 2, DEBUGLEVEL))
+
+def AddNoExceptionSharedObjects(env, names):
+    return AddCxxSharedObjects(env, names,
+        platform.getExceptionFlags(soenv, False)
+        + platform.getCompilerOptFlags(DEBUGLEVEL < 2, DEBUGLEVEL))
+
+def AddCxxSharedObjects(env, names, flags):
+    objects = []
+    for name in names:
+        objects.append(
+            env.SharedObject(
+                name,
+                CXXFLAGS = env['CXXFLAGS'] + flags
+            )
+        )
+    return objects
+
+if soenv['SYSTEM_LIBXSLT'] == 'YES':
+    _XSLTPROC = 'xsltproc'
+else:
+    _XSLTPROC = OUTDIR + '/bin/xsltproc'
+
+def SetComponentFile(self, library, componentFileBaseName):
+    env = self
+
+    componentFile = File(componentFileBaseName + '.component')
+    inbuildComponentFile = File(componentFileBaseName + '.inbuild.component')
+
+    outdirComponentDir = Dir(OUTDIR + '/xml/component/' + componentFile.srcnode().dir.path)
+
+    xsltenv = env.Clone()
+    xsltenv.Append(ENV = platform.getExecutableEnvironment(soenv))
+    finalComponent = xsltenv.Command(componentFile, componentFile.srcnode(),
+        action = [
+            _XSLTPROC + ' --nonet --stringparam uri "' + env['AOO_COMPONENTPREFIX'] + str(library[0]) + '"'
+            + ' -o $TARGET ' + env['SOLARENV'] + '/bin/createcomponent.xslt $SOURCE'
+        ]
+    )
+    inbuildComponent = xsltenv.Command(inbuildComponentFile, componentFile.srcnode(),
+        action = [
+            _XSLTPROC + ' --nonet --stringparam uri "' + platform.getLibraryLayerComponentPrefix('NONE') + str(library[0]) + '"'
+            + ' -o $TARGET ' + env['SOLARENV'] + '/bin/createcomponent.xslt $SOURCE'
+        ]
+    )
+
+    installs = []
+    installs += env.Install(outdirComponentDir, finalComponent)
+    installs += env.Install(outdirComponentDir, inbuildComponent)
+    return installs


[openoffice] 02/02: Add my gotoSCons parser/convert from gbuild to scons.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

damjan pushed a commit to branch scons-build
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit 1c93647b34c19875eb2476af6414246521a29b4e
Author: Damjan Jovanovic <da...@apache.org>
AuthorDate: Sun Feb 2 02:29:33 2020 +0200

    Add my gotoSCons parser/convert from gbuild to scons.
    
    Patch by: me
---
 gotoSCons/.gitignore                               |   4 +
 gotoSCons/pom.xml                                  |  21 ++
 .../openoffice/gotoSCons/GBuildConverter.java      |  82 ++++++++
 .../apache/openoffice/gotoSCons/GBuildParser.java  | 108 ++++++++++
 .../openoffice/gotoSCons/SConsConverter.java       | 231 +++++++++++++++++++++
 .../org/apache/openoffice/gotoSCons/Utils.java     |  37 ++++
 .../openoffice/gotoSCons/raw/FunctionNode.java     |  43 ++++
 .../apache/openoffice/gotoSCons/raw/ListNode.java  |  43 ++++
 .../org/apache/openoffice/gotoSCons/raw/Node.java  |  30 +++
 .../apache/openoffice/gotoSCons/raw/ValueNode.java |  40 ++++
 .../opeonoffice/gotoSCons/targets/BaseBinary.java  | 211 +++++++++++++++++++
 .../opeonoffice/gotoSCons/targets/BaseTarget.java  |  59 ++++++
 .../opeonoffice/gotoSCons/targets/Executable.java  | 107 ++++++++++
 .../opeonoffice/gotoSCons/targets/Library.java     |  99 +++++++++
 .../opeonoffice/gotoSCons/targets/Module.java      | 138 ++++++++++++
 .../apache/opeonoffice/gotoSCons/targets/Pkg.java  | 101 +++++++++
 .../opeonoffice/gotoSCons/targets/Repository.java  | 134 ++++++++++++
 17 files changed, 1488 insertions(+)

diff --git a/gotoSCons/.gitignore b/gotoSCons/.gitignore
new file mode 100644
index 0000000..4c04fd5
--- /dev/null
+++ b/gotoSCons/.gitignore
@@ -0,0 +1,4 @@
+.classpath
+.project
+.settings
+target/
diff --git a/gotoSCons/pom.xml b/gotoSCons/pom.xml
new file mode 100644
index 0000000..8a758f0
--- /dev/null
+++ b/gotoSCons/pom.xml
@@ -0,0 +1,21 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>local</groupId>
+  <artifactId>gotoSCons</artifactId>
+  <version>0.1-SNAPSHOT</version>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.1</version>
+        <configuration>
+          <source>1.7</source>
+          <target>1.7</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+    <name>gotoSCons</name>
+</project>
\ No newline at end of file
diff --git a/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/GBuildConverter.java b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/GBuildConverter.java
new file mode 100644
index 0000000..81cac93
--- /dev/null
+++ b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/GBuildConverter.java
@@ -0,0 +1,82 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+package org.apache.openoffice.gotoSCons;
+
+import java.io.File;
+import java.util.Set;
+import java.util.TreeSet;
+import org.apache.opeonoffice.gotoSCons.targets.Library;
+import org.apache.opeonoffice.gotoSCons.targets.Module;
+import org.apache.opeonoffice.gotoSCons.targets.Repository;
+
+public class GBuildConverter {
+    public static void main(String[] args) throws Exception {
+        if (args.length < 1) {
+            System.err.println("Needs args");
+            System.exit(1);
+        }
+        if (args[0].equals("parsingAnalysis")) {
+            parsingAnalysis(args);
+        } else if (args[0].equals("parseModule")) {
+            if (args.length < 2) {
+                throw new Exception("Needs path to Module_xxx.mk");
+            }
+            Module module = new Module(new File(args[1]));
+            Repository repo = new Repository(new File(
+                    module.getFilename().getParentFile().getParentFile(), "Repository.mk"));
+            new SConsConverter(repo, System.out).convertToSCons(module);
+        } else if (args[0].equals("parseLibrary")) {
+            if (args.length < 2) {
+                throw new Exception("Needs path to Library_xxx.mk");
+            }
+            Library library = new Library(new File(args[1]));
+            System.out.println(library);
+        } else {
+            throw new Exception("Unsupported args");
+        }
+    }
+
+    public static void parsingAnalysis(String[] args) throws Exception {
+        File dir = new File(args[1]);
+        int modules = 0;
+        int parsable = 0;
+        Set<String> parsed = new TreeSet<>();
+        for (File file : dir.listFiles()) {
+            if (file.isDirectory()) {
+                if (new File(new File(file, "prj"), "makefile.mk").exists()) {
+                    ++modules;
+                    try {
+                        Module module = new Module(new File(file, "Module_" + file.getName() + ".mk"));
+                        ++parsable;
+                        parsed.add(module.getName());
+                    } catch (Exception ex) {
+                        System.err.println("============");
+                        System.err.print(file.getName() + "#"); // for easy "module#message" separation into CSV
+                        ex.printStackTrace();
+                    }
+                }
+            }
+        }
+        System.out.println("Could parse: " + parsed.toString());
+        System.out.println("" + parsable + " out of " + modules + " gbuild modules are parseable");
+    }
+}
diff --git a/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/GBuildParser.java b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/GBuildParser.java
new file mode 100644
index 0000000..d35ffe2
--- /dev/null
+++ b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/GBuildParser.java
@@ -0,0 +1,108 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+package org.apache.openoffice.gotoSCons;
+
+import java.io.BufferedReader;
+import java.util.ArrayList;
+
+import org.apache.openoffice.gotoSCons.raw.FunctionNode;
+import org.apache.openoffice.gotoSCons.raw.ListNode;
+import org.apache.openoffice.gotoSCons.raw.Node;
+import org.apache.openoffice.gotoSCons.raw.ValueNode;
+
+public class GBuildParser {
+    
+    public ListNode parse(BufferedReader reader) throws Exception {
+        String fullLine = "";
+        String line;
+        ArrayList<Node> nodes = new ArrayList<>();
+        while ((line = reader.readLine()) != null) {
+            if (line.endsWith("\\")) {
+                fullLine += line.substring(0, line.length() - 1);
+            } else {
+                Node node = parseLine(fullLine + line);
+                fullLine = "";
+                if (node != null) {
+                    nodes.add(node);
+                }
+            }
+        }
+        
+        ListNode listNode = new ListNode(nodes.toArray(new Node[0]));
+        return listNode;
+    }
+    
+    private Node parseLine(String line) throws Exception {
+        if (line.startsWith("#")) {
+            return null;
+        }
+        
+        if (line.isEmpty()) {
+            return null;
+        }
+        
+        //System.out.println(line);
+        return evaluateExpression(line);
+    }
+    
+    private Node evaluateExpression(String expr) throws Exception {
+        // $(gb_STDLIBS)
+        // $(call gb_Library_Library,fileacc)
+        // $(call gb_Library_set_include,fileacc,$$(INCLUDE) -I$(SRCDIR)/fileaccess/inc)
+        if (expr.startsWith("$(")) {
+            StringBuilder token = new StringBuilder();
+            int brackets = 1;
+            int i;
+            for (i = 2; i < expr.length(); i++) {
+                if (expr.charAt(i) == ')') {
+                    --brackets;
+                    if (brackets == 0) {
+                        break;
+                    }
+                } else if (expr.charAt(i) == '(') {
+                    brackets++;
+                }
+                token.append(expr.charAt(i));
+            }
+            if (i < (expr.length() - 1)) {
+                throw new Exception("Expression ends early; explicit dependencies are not supported! " +
+                        "Expression was: " + expr);
+            }
+            
+            int firstSpace = token.indexOf(" ");
+            if (firstSpace > 0) {
+                String function = token.substring(0, firstSpace);
+                Node args = evaluateExpression(token.substring(firstSpace + 1));
+                return new FunctionNode(function, args);
+            } else {
+                return new ValueNode(expr);
+            }
+        } else {
+            if (expr.contains(" : ")) {
+                throw new Exception("Explicit dependencies are not supported! " +
+                        "Expression was: " + expr);
+            }
+            return new ValueNode(expr);
+        }
+    }
+    
+}
diff --git a/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/SConsConverter.java b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/SConsConverter.java
new file mode 100644
index 0000000..9bdcef7
--- /dev/null
+++ b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/SConsConverter.java
@@ -0,0 +1,231 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+package org.apache.openoffice.gotoSCons;
+
+import java.io.File;
+import java.io.PrintStream;
+import java.util.Map;
+import org.apache.opeonoffice.gotoSCons.targets.BaseBinary;
+import org.apache.opeonoffice.gotoSCons.targets.Executable;
+import org.apache.opeonoffice.gotoSCons.targets.Library;
+import org.apache.opeonoffice.gotoSCons.targets.Module;
+import org.apache.opeonoffice.gotoSCons.targets.Pkg;
+import org.apache.opeonoffice.gotoSCons.targets.Repository;
+
+public class SConsConverter {
+    private Repository repo;
+    private PrintStream out;
+    
+    public SConsConverter(Repository repo, PrintStream out) {
+        this.repo = repo;
+        this.out = out;
+    }
+    
+    public void convertToSCons(Module module) throws Exception {
+        for (Library library : module.getLibraries().values()) {
+            convertLibrary(library);
+        }
+        
+        for (Executable exe : module.getExecutables().values()) {
+            convertExecutable(exe);
+        }
+        
+        for (Pkg pkg : module.getPackages().values()) {
+            for (Map.Entry<String, String> entry : pkg.getFilesToFrom().entrySet()) {
+                String toPath = entry.getKey();
+                String fromPath = pkg.getBaseDir() + '/' + entry.getValue();
+                
+                File moduleDir = module.getFilename().getParentFile().getCanonicalFile();
+                String expandedFromPath = fromPath.replace("$(SRCDIR)", moduleDir.getParentFile().getCanonicalPath());
+                String moduleRelativeFromPath;
+                if (expandedFromPath.startsWith(moduleDir.getCanonicalPath())) {
+                    moduleRelativeFromPath = expandedFromPath.substring(moduleDir.getCanonicalPath().length() + 1);
+                } else {
+                    throw new Exception("Cannot find module relative path to " + fromPath);
+                }
+                
+                out.println(String.format("Install('${OUTDIR}/%s', '%s')", toPath, moduleRelativeFromPath));
+            }
+            out.println();
+        }
+    }
+    
+    private void convertLibrary(Library library) throws Exception {
+        String objectsVariable = convertObjects(library);
+
+        String layer = repo.getLibraryLayer(library.getName());
+        out.println(String.format("%s = AOOSharedLibrary(", library.getName()));
+        out.println(String.format("    '%s',", library.getName()));
+        out.println(String.format("    '%s',", layer));
+        out.println(String.format("    %s.objects", objectsVariable));
+        out.println(String.format(")"));
+
+        if (!library.getLinkedLibs().isEmpty()) {
+            out.println(String.format("%s.AddLinkedLibs([", library.getName()));
+            boolean first = true;
+            for (String linkedLib : library.getLinkedLibs()) {
+                if (!first) {
+                    out.println(",");
+                }
+                out.print("    '" + linkedLib + "'");
+                first = false;
+            }
+            out.println();
+            out.println("])");
+        }
+
+        String componentFile = library.getComponentFile();
+        if (componentFile != null) {
+            int firstSlash = componentFile.indexOf('/');
+            if (firstSlash < 0) {
+                throw new Exception("Invalid filename " + componentFile);
+            }
+
+            out.println(String.format("%s.SetComponentFile('%s')",
+                    library.getName(), componentFile.substring(firstSlash + 1)));
+        }
+
+        out.println(String.format("%s.InstallTo('${OUTDIR}/lib')", library.getName()));
+        out.println();
+    }
+    
+    private void convertExecutable(Executable exe) throws Exception {
+        String objectsVariable = convertObjects(exe);
+
+        String layer = repo.getExecutableLayer(exe.getName());
+        out.println(String.format("%s = AOOExecutable(", exe.getName()));
+        out.println(String.format("    '%s',", exe.getName()));
+        out.println(String.format("    '%s',", layer));
+        out.println(String.format("    %s.objects", objectsVariable));
+        out.println(String.format(")"));
+        
+        if (exe.isTargetTypeSet()) {
+            out.println(String.format("%s.SetTargetTypeGUI()",
+                    exe.getName(),
+                    exe.isIsTargetTypeGUI() ? "True" : "False"));
+        }
+
+        if (!exe.getLinkedLibs().isEmpty()) {
+            out.println(String.format("%s.AddLinkedLibs([", exe.getName()));
+            boolean first = true;
+            for (String linkedLib : exe.getLinkedLibs()) {
+                if (!first) {
+                    out.println(",");
+                }
+                out.print("    '" + linkedLib + "'");
+                first = false;
+            }
+            out.println();
+            out.println("])");
+        }
+
+        out.println(String.format("%s.InstallTo('${OUTDIR}/bin')", exe.getName()));
+        out.println();
+    }
+    
+    private String convertObjects(BaseBinary binary) throws Exception {
+        String objectsVariable = binary.getName() + "Objects";
+        if (binary.getExceptionObjects().isEmpty()) {
+            throw new Exception("How can a binary have no source files?");
+        }
+        out.println(objectsVariable + " = AOOSharedObjects()");
+        
+        if (!binary.getApis().isEmpty()) {
+            out.println(objectsVariable + ".AddAPI([");
+            boolean first = true;
+            for (String api : binary.getApis()) {
+                if (!first) {
+                    out.println(",");
+                }
+                out.print("    '" + api + "'");
+                first = false;
+            }
+            out.println();
+            out.println("])");
+        }
+            
+        if (!binary.getIncludes().isEmpty()) {
+            out.println(objectsVariable + ".AddInclude([");
+            boolean first = true;
+            for (String include : binary.getIncludes()) {
+                if (include.equals("$$(INCLUDE)")) {
+                    continue;
+                }
+                if (include.startsWith("-I")) {
+                    include = include.substring(2);
+                }
+                if (include.startsWith("$(SRCDIR)/")) {
+                    int firstSlash = include.indexOf('/');
+                    int secondSlash = include.indexOf('/', firstSlash + 1);
+                    include = include.substring(secondSlash + 1);
+                }
+
+                if (!first) {
+                    out.println(",");
+                }
+                out.print("    '" + include + "'");
+                first = false;
+            }
+            out.println();
+            out.println("])");
+        }
+
+        if (!binary.getDefs().isEmpty()) {
+            out.println(objectsVariable + ".AddDefs([");
+            boolean first = true;
+            for (String def : binary.getDefs()) {
+                if (!first) {
+                    out.println(",");
+                }
+                if (def.startsWith("-D")) {
+                    def = def.substring(2);
+                }
+                out.print("    '" + def + "'");
+                first = false;
+            }
+            out.println();
+            out.println("])");
+        }
+
+        if (!binary.getExceptionObjects().isEmpty()) {
+            out.println(objectsVariable + ".AddCxxExceptionSources([");
+            boolean first = true;
+            for (String exceptionObject : binary.getExceptionObjects()) {
+                if (!first) {
+                    out.println(",");
+                }
+                // in: fileaccess/source/FileAccess
+                // out: source/FileAccess.cxx
+                int firstSlash = exceptionObject.indexOf('/');
+                if (firstSlash < 0) {
+                    throw new Exception("Invalid filename " + exceptionObject);
+                }
+                out.print("    '" + exceptionObject.substring(firstSlash + 1) + ".cxx'");
+                first = false;
+            }
+            out.println();
+            out.println("])");
+        }
+        
+        return objectsVariable;
+    }
+}
diff --git a/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/Utils.java b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/Utils.java
new file mode 100644
index 0000000..cfae779
--- /dev/null
+++ b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/Utils.java
@@ -0,0 +1,37 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+package org.apache.openoffice.gotoSCons;
+
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+
+public class Utils {
+    public static String[] spaceSeparatedTokens(String text) throws Exception {
+        StringTokenizer tokenizer = new StringTokenizer(text, " \t", false);
+        ArrayList<String> tokens = new ArrayList<>();
+        while (tokenizer.hasMoreElements()) {
+            tokens.add((String)tokenizer.nextElement());
+        }
+        return tokens.toArray(new String[0]);
+    }
+
+}
diff --git a/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/raw/FunctionNode.java b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/raw/FunctionNode.java
new file mode 100644
index 0000000..792ea92
--- /dev/null
+++ b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/raw/FunctionNode.java
@@ -0,0 +1,43 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+package org.apache.openoffice.gotoSCons.raw;
+
+public class FunctionNode extends Node {
+    public String function;
+    public Node child;
+    
+    public FunctionNode(String function, Node child) {
+        this.function = function;
+        this.child = child;
+    }
+    
+    @Override
+    protected void dump(String space) {
+        System.out.println(space + "function " + function);
+        child.dump(space + "    ");
+    }
+
+    @Override
+    public String toString() {
+        return function + "(...)";
+    }
+}
diff --git a/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/raw/ListNode.java b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/raw/ListNode.java
new file mode 100644
index 0000000..8a6c26b
--- /dev/null
+++ b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/raw/ListNode.java
@@ -0,0 +1,43 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+package org.apache.openoffice.gotoSCons.raw;
+
+public class ListNode extends Node {
+    public Node[] children;
+    
+    public ListNode(Node[] children) {
+        this.children = children;
+    }
+    
+    @Override
+    protected void dump(String space) {
+        System.out.println(space + "(list)");
+        for (Node child : children) {
+            child.dump(space + "    ");
+        }
+    }
+
+    @Override
+    public String toString() {
+        return children.toString();
+    }
+}
diff --git a/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/raw/Node.java b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/raw/Node.java
new file mode 100644
index 0000000..d9b62d1
--- /dev/null
+++ b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/raw/Node.java
@@ -0,0 +1,30 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+package org.apache.openoffice.gotoSCons.raw;
+
+public abstract class Node {
+    public final void dump() {
+        dump("");
+    }
+    
+    protected abstract void dump(String space);
+}
diff --git a/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/raw/ValueNode.java b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/raw/ValueNode.java
new file mode 100644
index 0000000..823208e
--- /dev/null
+++ b/gotoSCons/src/main/java/org/apache/openoffice/gotoSCons/raw/ValueNode.java
@@ -0,0 +1,40 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+package org.apache.openoffice.gotoSCons.raw;
+
+public class ValueNode extends Node {
+    public String value;
+    
+    public ValueNode(String value) {
+        this.value = value;
+    }
+    
+    @Override
+    protected void dump(String space) {
+        System.out.println(space + value);
+    }
+
+    @Override
+    public String toString() {
+        return value;
+    }
+}
diff --git a/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/BaseBinary.java b/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/BaseBinary.java
new file mode 100644
index 0000000..874f61e
--- /dev/null
+++ b/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/BaseBinary.java
@@ -0,0 +1,211 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+package org.apache.opeonoffice.gotoSCons.targets;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.TreeSet;
+import org.apache.openoffice.gotoSCons.GBuildParser;
+import org.apache.openoffice.gotoSCons.Utils;
+import org.apache.openoffice.gotoSCons.raw.ListNode;
+
+public abstract class BaseBinary extends BaseTarget {
+    private File filename;
+    protected String name;
+    private Set<String> packageHeaders = new TreeSet<>();
+    private String precompiledHeader;
+    private Set<String> apis = new TreeSet<>();
+    private Set<String> defs = new TreeSet<>();
+    private Set<String> includes = new TreeSet<>();
+    private Set<String> exceptionObjects = new TreeSet<>();
+    private Set<String> noexceptionObjects = new TreeSet<>();
+    private Set<String> linkedLibs = new TreeSet<>();
+
+    public BaseBinary(File filename) throws Exception {
+        this.filename = filename;
+        try (
+                BufferedReader reader = new BufferedReader(new InputStreamReader(
+                        new FileInputStream(filename)))
+                ) {
+            ListNode rootNode = new GBuildParser().parse(reader);
+            parse(rootNode);
+        }
+    }
+
+    protected void parseAddApi(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Exception("Expected 2 args, got " + Arrays.toString(args));
+        }
+        if (!args[0].equals(name)) {
+            throw new Exception("Target name isn't " + name);
+        }
+        for (String arg : Utils.spaceSeparatedTokens(args[1])) {
+            if (!apis.add(arg)) {
+                throw new Exception("Duplicate API " + arg);
+            }
+        }
+    }
+    
+    protected void parseAddDefs(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Exception("Expected 2 args, got " + Arrays.toString(args));
+        }
+        if (!args[0].equals(name)) {
+            throw new Exception("Target name isn't " + name);
+        }
+        for (String arg : Utils.spaceSeparatedTokens(args[1])) {
+            if (!defs.add(arg)) {
+                throw new Exception("Duplicate def " + arg);
+            }
+        }
+    }
+    
+    protected void parseAddExceptionObjects(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Exception("Expected 2 args, got " + Arrays.toString(args));
+        }
+        if (!args[0].equals(name)) {
+            throw new Exception("Target name isn't " + name);
+        }
+
+        for (String arg : Utils.spaceSeparatedTokens(args[1])) {
+            if (!exceptionObjects.add(arg)) {
+                throw new Exception("Duplicate exception object " + arg);
+            }
+        }
+    }
+
+    protected void parseAddNoExceptionObjects(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Exception("Expected 2 args, got " + Arrays.toString(args));
+        }
+        if (!args[0].equals(name)) {
+            throw new Exception("Target name isn't " + name);
+        }
+
+        for (String arg : Utils.spaceSeparatedTokens(args[1])) {
+            if (!noexceptionObjects.add(arg)) {
+                throw new Exception("Duplicate noexception object " + arg);
+            }
+        }
+    }
+    
+    protected void parseAddLinkedLibs(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Exception("Expected 2 args, got " + Arrays.toString(args));
+        }
+        if (!args[0].equals(name)) {
+            throw new Exception("Target name isn't " + name);
+        }
+
+        for (String arg : Utils.spaceSeparatedTokens(args[1])) {
+            if (!linkedLibs.add(arg)) {
+                throw new Exception("Duplicate linked lib " + arg);
+            }
+        }
+    }
+    
+    protected void parseAddPackageHeaders(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Exception("Expected 2 args, got " + Arrays.toString(args));
+        }
+        if (!args[0].equals(name)) {
+            throw new Exception("Target name isn't " + name);
+        }
+
+        for (String arg : Utils.spaceSeparatedTokens(args[1])) {
+            if (!packageHeaders.add(arg)) {
+                throw new Exception("Duplicate package header " + arg);
+            }
+        }
+    }
+    
+    protected void parseAddPrecompiledHeader(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Exception("Expected 2 args, got " + Arrays.toString(args));
+        }
+        if (!args[0].equals(name)) {
+            throw new Exception("Target name isn't " + name);
+        }
+        if (precompiledHeader != null) {
+            throw new Exception("Precompiled header already set");
+        } else {
+            precompiledHeader = args[1];
+        }
+    }
+    
+    protected void parseSetInclude(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Exception("Expected 2 args, got " + Arrays.toString(args));
+        }
+        if (!args[0].equals(name)) {
+            throw new Exception("Target name isn't " + name);
+        }
+
+        for (String arg : Utils.spaceSeparatedTokens(args[1])) {
+            if (!includes.add(arg)) {
+                throw new Exception("Duplicate include " + arg);
+            }
+        }
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Set<String> getApis() {
+        return apis;
+    }
+
+    public Set<String> getDefs() {
+        return defs;
+    }
+
+    public Set<String> getExceptionObjects() {
+        return exceptionObjects;
+    }
+
+    public Set<String> getIncludes() {
+        return includes;
+    }
+
+    public Set<String> getLinkedLibs() {
+        return linkedLibs;
+    }
+
+    public Set<String> getNoexceptionObjects() {
+        return noexceptionObjects;
+    }
+
+    public Set<String> getPackageHeaders() {
+        return packageHeaders;
+    }
+
+    public String getPrecompiledHeader() {
+        return precompiledHeader;
+    }
+
+}
diff --git a/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/BaseTarget.java b/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/BaseTarget.java
new file mode 100644
index 0000000..b424ac9
--- /dev/null
+++ b/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/BaseTarget.java
@@ -0,0 +1,59 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+package org.apache.opeonoffice.gotoSCons.targets;
+
+import org.apache.openoffice.gotoSCons.raw.FunctionNode;
+import org.apache.openoffice.gotoSCons.raw.ListNode;
+import org.apache.openoffice.gotoSCons.raw.Node;
+
+public abstract class BaseTarget {
+    
+    protected void parse(ListNode root) throws Exception {
+        for (Node child : root.children) {
+            if (child instanceof FunctionNode) {
+                FunctionNode functionNode = (FunctionNode)child;
+                if (functionNode.function.equals("eval")) {
+                    parseEval(functionNode);
+                } else {
+                    throw new Exception("Top-level function isn't \"eval\" but \"" + functionNode.function + "\"");
+                }
+            } else {
+                throw new Exception("Top-level declaration isn't a function but " + child.toString());
+            }
+        }
+    }
+    
+    protected void parseEval(FunctionNode functionNode) throws Exception {
+        if (functionNode.child instanceof FunctionNode) {
+            FunctionNode nestedFunction = (FunctionNode)functionNode.child;
+            if (nestedFunction.function.equals("call")) {
+                parseCall(nestedFunction.child);
+            } else {
+                throw new Exception("eval's nested function isn't \"call\" but \"" + functionNode.function + "\"");
+            }
+        } else {
+            throw new Exception("eval child not a function but " + functionNode.child.toString());
+        }
+    }
+
+    abstract protected void parseCall(Node child) throws Exception;
+}
diff --git a/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/Executable.java b/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/Executable.java
new file mode 100644
index 0000000..09c52d3
--- /dev/null
+++ b/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/Executable.java
@@ -0,0 +1,107 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+package org.apache.opeonoffice.gotoSCons.targets;
+
+import java.io.File;
+import java.util.Arrays;
+import org.apache.openoffice.gotoSCons.raw.Node;
+import org.apache.openoffice.gotoSCons.raw.ValueNode;
+
+public class Executable extends BaseBinary {
+    private boolean isTargetTypeSet;
+    private boolean isTargetTypeGUI;
+
+    public Executable(File filename) throws Exception {
+        super(filename);
+    }
+
+    @Override
+    protected void parseCall(Node argsNode) throws Exception {
+        if (argsNode instanceof ValueNode) {
+            String value = ((ValueNode)argsNode).value;
+            String[] tokens = value.split(",");
+            
+            String function = tokens[0].trim();
+            String[] args = Arrays.copyOfRange(tokens, 1, tokens.length);
+            
+            if (function.equals("gb_Executable_Executable")) {
+                parseExecutableExecutable(args);
+            } else if (function.equals("gb_Executable_add_api")) {
+                parseAddApi(args);
+            } else if (function.equals("gb_Executable_add_defs")) {
+                parseAddDefs(args);
+            } else if (function.equals("gb_Executable_add_exception_objects")) {
+                parseAddExceptionObjects(args);
+            } else if (function.equals("gb_Executable_add_noexception_objects")) {
+                parseAddNoExceptionObjects(args);
+            } else if (function.equals("gb_Executable_add_linked_libs")) {
+                parseAddLinkedLibs(args);
+            } else if (function.equals("gb_Executable_add_package_headers")) {
+                parseAddPackageHeaders(args);
+            } else if (function.equals("gb_Executable_add_precompiled_header")) {
+                parseAddPrecompiledHeader(args);
+            } else if (function.equals("gb_Executable_set_include")) {
+                parseSetInclude(args);
+            } else if (function.equals("gb_Executable_set_targettype_gui")) {
+                parseSetTargetTypeGUI(args);
+            } else {
+                throw new Exception("UNHANDLED FUNCTION " + function);
+            }
+        } else {
+            throw new Exception("Call args not a value");
+        }
+
+    }
+    
+    private void parseExecutableExecutable(String[] args) throws Exception {
+        if (args.length != 1) {
+            throw new Exception("Expected 1 arg, got " + Arrays.toString(args));
+        }
+        this.name = args[0];
+    }
+
+    private void parseSetTargetTypeGUI(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Exception("Expected 2 args, got " + Arrays.toString(args));
+        }
+        if (!args[0].equals(name)) {
+            throw new Exception("Target name isn't " + name);
+        }
+        isTargetTypeSet = true;
+        String yesNo = args[1].trim();
+        if (yesNo.equals("YES")) {
+            isTargetTypeGUI = true;
+        } else if (yesNo.equals("NO")) {
+            isTargetTypeGUI = false;
+        } else {
+            throw new Exception("Target type GUI isn't YES or NO but " + yesNo);
+        }
+    }
+    
+    public boolean isTargetTypeSet() {
+        return isTargetTypeSet;
+    }
+
+    public boolean isIsTargetTypeGUI() {
+        return isTargetTypeGUI;
+    }
+}
diff --git a/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/Library.java b/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/Library.java
new file mode 100644
index 0000000..9e8f828
--- /dev/null
+++ b/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/Library.java
@@ -0,0 +1,99 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+package org.apache.opeonoffice.gotoSCons.targets;
+
+import java.io.File;
+import java.util.Arrays;
+import org.apache.openoffice.gotoSCons.raw.Node;
+import org.apache.openoffice.gotoSCons.raw.ValueNode;
+
+public class Library extends BaseBinary {
+    private File filename;
+    private String componentFile;
+    
+    public Library(File filename) throws Exception {
+        super(filename);
+    }
+    
+    @Override
+    protected void parseCall(Node argsNode) throws Exception {
+        if (argsNode instanceof ValueNode) {
+            String value = ((ValueNode)argsNode).value;
+            String[] tokens = value.split(",");
+            
+            String function = tokens[0].trim();
+            String[] args = Arrays.copyOfRange(tokens, 1, tokens.length);
+            
+            if (function.equals("gb_Library_Library")) {
+                parseLibraryLibrary(args);
+            } else if (function.equals("gb_Library_add_api")) {
+                parseAddApi(args);
+            } else if (function.equals("gb_Library_add_defs")) {
+                parseAddDefs(args);
+            } else if (function.equals("gb_Library_add_exception_objects")) {
+                parseAddExceptionObjects(args);
+            } else if (function.equals("gb_Library_add_noexception_objects")) {
+                parseAddNoExceptionObjects(args);
+            } else if (function.equals("gb_Library_add_linked_libs")) {
+                parseAddLinkedLibs(args);
+            } else if (function.equals("gb_Library_add_package_headers")) {
+                parseAddPackageHeaders(args);
+            } else if (function.equals("gb_Library_add_precompiled_header")) {
+                parseAddPrecompiledHeader(args);
+            } else if (function.equals("gb_Library_set_componentfile")) {
+                parseSetComponentFile(args);
+            } else if (function.equals("gb_Library_set_include")) {
+                parseSetInclude(args);
+            } else {
+                throw new Exception("UNHANDLED FUNCTION " + function);
+            }
+        } else {
+            throw new Exception("Call args not a value");
+        }
+    }
+    
+    private void parseLibraryLibrary(String[] args) throws Exception {
+        if (args.length != 1) {
+            throw new Exception("Expected 1 arg, got " + Arrays.toString(args));
+        }
+        this.name = args[0];
+    }
+
+    private void parseSetComponentFile(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Exception("Expected 2 args, got " + Arrays.toString(args));
+        }
+        if (!args[0].equals(name)) {
+            throw new Exception("Library isn't " + name);
+        }
+
+        if (componentFile != null) {
+            throw new Exception("Component file already set");
+        } else {
+            componentFile = args[1];
+        }
+    }
+    
+    public String getComponentFile() {
+        return componentFile;
+    }
+}
diff --git a/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/Module.java b/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/Module.java
new file mode 100644
index 0000000..5d20234
--- /dev/null
+++ b/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/Module.java
@@ -0,0 +1,138 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+package org.apache.opeonoffice.gotoSCons.targets;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import org.apache.openoffice.gotoSCons.GBuildParser;
+import org.apache.openoffice.gotoSCons.Utils;
+import org.apache.openoffice.gotoSCons.raw.ListNode;
+import org.apache.openoffice.gotoSCons.raw.Node;
+import org.apache.openoffice.gotoSCons.raw.ValueNode;
+
+public class Module extends BaseTarget {
+    private File filename;
+    private String name;
+    private Map<String, Library> libraries = new TreeMap<>();
+    private Map<String, Executable> executables = new TreeMap<>();
+    private TreeSet<String> targets = new TreeSet<>();
+    private Map<String, Pkg> packages = new TreeMap<>();
+    
+    public Module(File filename) throws Exception {
+        this.filename = filename;
+        try (
+                BufferedReader reader = new BufferedReader(new InputStreamReader(
+                        new FileInputStream(filename)))
+                ) {
+            ListNode rootNode = new GBuildParser().parse(reader);
+            parse(rootNode);
+        }
+    }
+    
+    @Override
+    protected void parseCall(Node argsNode) throws Exception {
+        if (argsNode instanceof ValueNode) {
+            String value = ((ValueNode)argsNode).value;
+            String[] tokens = value.split(",");
+            
+            String function = tokens[0].trim();
+            String[] args = Arrays.copyOfRange(tokens, 1, tokens.length);
+            
+            if (function.equals("gb_Module_Module")) {
+                parseModuleModule(args);
+            } else if (function.equals("gb_Module_add_targets")) {
+                parseModuleAddTargets(args);
+            } else {
+                throw new Exception("Unhandled function " + function);
+            }
+        } else {
+            throw new Exception("Call args not a value");
+        }
+    }
+    
+    private void parseModuleModule(String[] args) throws Exception {
+        if (args.length != 1) {
+            throw new Exception("Expected 1 arg, got " + Arrays.toString(args));
+        }
+        this.name = args[0];
+    }
+    
+    private void parseModuleAddTargets(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Exception("Expected 2 args, got " + Arrays.toString(args));
+        }
+        if (!args[0].equals(name)) {
+            throw new Exception("Module isn't " + name);
+        }
+        for (String arg : Utils.spaceSeparatedTokens(args[1])) {
+            if (arg.startsWith("Executable_")) {
+                Executable exe = new Executable(new File(filename.getParentFile(), arg + ".mk"));
+                if (executables.put(arg, exe) != null) {
+                    throw new Exception("Duplicate add of target " + arg);
+                }
+            } else if (arg.startsWith("Library_")) {
+                Library library = new Library(new File(filename.getParentFile(), arg + ".mk"));
+                if (libraries.put(arg, library) != null) {
+                    throw new Exception("Duplicate add of target " + arg);
+                }
+            } else if (arg.startsWith("Package_")) {
+                Pkg pkg = new Pkg(new File(filename.getParentFile(), arg + ".mk"));
+                if (packages.put(arg, pkg) != null) {
+                    throw new Exception("Duplicate add of target " + arg);
+                }
+            } else {
+                throw new Exception("Unsupported target " + arg);
+            }
+        }
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public File getFilename() {
+        return filename;
+    }
+    
+    public Map<String, Library> getLibraries() {
+        return libraries;
+    }
+
+    public Map<String, Executable> getExecutables() {
+        return executables;
+    }
+    
+    public Map<String, Pkg> getPackages() {
+        return packages;
+    }
+
+    @Override
+    public String toString() {
+        return "Module{" + "filename=" + filename + ", name=" + name + ", targets=" + targets + '}';
+    }
+}
diff --git a/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/Pkg.java b/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/Pkg.java
new file mode 100644
index 0000000..a9b85c6
--- /dev/null
+++ b/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/Pkg.java
@@ -0,0 +1,101 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+package org.apache.opeonoffice.gotoSCons.targets;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.TreeMap;
+import org.apache.openoffice.gotoSCons.GBuildParser;
+import org.apache.openoffice.gotoSCons.raw.ListNode;
+import org.apache.openoffice.gotoSCons.raw.Node;
+import org.apache.openoffice.gotoSCons.raw.ValueNode;
+
+public class Pkg extends BaseTarget {
+    private File filename;
+    private String name;
+    private String baseDir;
+    private Map<String, String> filesToFrom = new TreeMap<>();
+    
+    public Pkg(File filename) throws Exception {
+        this.filename = filename;
+        try (
+                BufferedReader reader = new BufferedReader(new InputStreamReader(
+                        new FileInputStream(filename)))
+                ) {
+            ListNode rootNode = new GBuildParser().parse(reader);
+            parse(rootNode);
+        }
+    }
+
+    @Override
+    protected void parseCall(Node argsNode) throws Exception {
+        if (argsNode instanceof ValueNode) {
+            String value = ((ValueNode)argsNode).value;
+            String[] tokens = value.split(",");
+            
+            String function = tokens[0].trim();
+            String[] args = Arrays.copyOfRange(tokens, 1, tokens.length);
+            
+            if (function.equals("gb_Package_Package")) {
+                parsePackagePackage(args);
+            } else if (function.equals("gb_Package_add_file")) {
+                parseAddFile(args);
+            } else {
+                throw new Exception("UNHANDLED FUNCTION " + function);
+            }
+        } else {
+            throw new Exception("Call args not a value");
+        }
+    }
+
+    private void parsePackagePackage(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Exception("Expected 2 arg, got " + Arrays.toString(args));
+        }
+        this.name = args[0];
+        this.baseDir = args[1];
+    }
+
+    private void parseAddFile(String[] args) throws Exception {
+        if (args.length != 3) {
+            throw new Exception("Expected 3 args, got " + Arrays.toString(args));
+        }
+        if (!args[0].equals(name)) {
+            throw new Exception("Package isn't " + name);
+        }
+        if (filesToFrom.put(args[1], args[2]) != null) {
+            throw new Exception("Duplicate package of file " + args[2] + " to " + args[1]);
+        }
+    }
+
+    public String getBaseDir() {
+        return baseDir;
+    }
+
+    public Map<String, String> getFilesToFrom() {
+        return filesToFrom;
+    }
+}
diff --git a/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/Repository.java b/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/Repository.java
new file mode 100644
index 0000000..5157ccd
--- /dev/null
+++ b/gotoSCons/src/main/java/org/apache/opeonoffice/gotoSCons/targets/Repository.java
@@ -0,0 +1,134 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+package org.apache.opeonoffice.gotoSCons.targets;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.TreeMap;
+import org.apache.openoffice.gotoSCons.GBuildParser;
+import org.apache.openoffice.gotoSCons.Utils;
+import org.apache.openoffice.gotoSCons.raw.ListNode;
+import org.apache.openoffice.gotoSCons.raw.Node;
+import org.apache.openoffice.gotoSCons.raw.ValueNode;
+
+public class Repository extends BaseTarget {
+    private File filename;
+    private String name;
+    private Map<String, String> libraryLayers = new TreeMap<>();
+    private Map<String, String> executableLayers = new TreeMap<>();
+    private Map<String, String> staticLibraryLayers = new TreeMap<>();
+    
+    public Repository(File filename) throws Exception {
+        this.filename = filename;
+        try (
+                BufferedReader reader = new BufferedReader(new InputStreamReader(
+                        new FileInputStream(filename)))
+                ) {
+            ListNode rootNode = new GBuildParser().parse(reader);
+            parse(rootNode);
+        }
+    }
+    
+    @Override
+    protected void parseCall(Node argsNode) throws Exception {
+        if (argsNode instanceof ValueNode) {
+            String value = ((ValueNode)argsNode).value;
+            String[] tokens = value.split(",");
+            
+            String function = tokens[0];
+            String[] args = Arrays.copyOfRange(tokens, 1, tokens.length);
+            
+            if (function.equals("gb_Helper_register_repository")) {
+                parseRegisterRepository(args);
+            } else if (function.equals("gb_Helper_register_executables")) {
+                parseRegisterExecutables(args);
+            } else if (function.equals("gb_Helper_register_libraries")) {
+                parseRegisterLibraries(args);
+            } else if (function.equals("gb_Helper_register_static_libraries")) {
+                parseRegisterStaticLibraries(args);
+            } else {
+                throw new Exception("Unhandled function " + function);
+            }
+        } else {
+            throw new Exception("Call args not a value");
+        }
+    }
+
+    private void parseRegisterRepository(String[] args) throws Exception {
+        if (args.length != 1) {
+            throw new Exception("Expected 1 arg, got " + args);
+        }
+        this.name = args[0];
+    }    
+    
+    private void parseRegisterExecutables(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Exception("Expected 2 args, got " + args);
+        }
+        String layer = args[0];
+        for (String arg : Utils.spaceSeparatedTokens(args[1])) {
+            if (executableLayers.put(arg, layer) != null) {
+                throw new Exception("Duplicate executable " + arg);
+            }
+        }
+    }
+
+    private void parseRegisterLibraries(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Exception("Expected 2 args, got " + args);
+        }
+        String layer = args[0];
+        for (String arg : Utils.spaceSeparatedTokens(args[1])) {
+            if (libraryLayers.put(arg, layer) != null) {
+                throw new Exception("Duplicate librarry " + arg);
+            }
+        }
+    }
+
+    private void parseRegisterStaticLibraries(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Exception("Expected 2 args, got " + args);
+        }
+        String layer = args[0];
+        for (String arg : Utils.spaceSeparatedTokens(args[1])) {
+            if (staticLibraryLayers.put(arg, layer) != null) {
+                throw new Exception("Duplicate librarry " + arg);
+            }
+        }
+    }
+    
+    public String getExecutableLayer(String executable) {
+        return executableLayers.get(executable);
+    }
+    
+    public String getLibraryLayer(String library) {
+        return libraryLayers.get(library);
+    }
+    
+    public String getStaticLibraryLayer(String library) {
+        return staticLibraryLayers.get(library);
+    }
+}