Decorator patter and initial build

This commit is contained in:
Bassem Girgis
2018-03-30 11:00:14 -05:00
parent 43c4edced5
commit 1806d6a1f2
30 changed files with 2857 additions and 0 deletions

3
src/site_scons/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
__pycache__/

View File

@@ -0,0 +1,62 @@
#
# This file is part of cpp-patterns.
#
# cpp-patterns is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cpp-patterns is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cpp-patterns. If not, see <http://www.gnu.org/licenses/>.
#
from .RunableTarget import RunableTarget
class Executable(RunableTarget):
def __init__(
self, env, name, sources, localStaticLibs, localSharedLibs,
externalLibs, isBin
):
self.__target = None
self.__isBin = isBin
super(Executable, self).__init__(
env, name, sources, localStaticLibs, localSharedLibs, externalLibs
)
self.writeScript()
self.env.Install(self.installDir, self.target)
@property
def installDir(self):
return self.binDir if self.__isBin else \
self.etcDir
@property
def scriptFileDir(self):
return self.installDir
@property
def target(self):
if self.__target is None:
self.__target = \
self.env.Program(target=self.name,
source=self.sources,
LIBS=self.localSharedLibsNames + self.externalLibsNames,
LIBPATH=self.env['LIBPATH'] +
self.externalLibsPaths,
CPPPATH=self.env['CPPPATH'] +
self.externalLibsIncludes,
CPPFLAGS=self.cppFlags,
LINKFLAGS=self.linkFlags)
return self.__target

View File

@@ -0,0 +1,163 @@
#
# This file is part of cpp-patterns.
#
# cpp-patterns is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cpp-patterns is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cpp-patterns. If not, see <http://www.gnu.org/licenses/>.
#
import os
class LocalTarget(object):
def __init__(
self, env, name, sources, localStaticLibs, localSharedLibs, externalLibs
):
self.__env = env
self.__name = name
self.__sources = sources
self.__localStaticLibs = localStaticLibs
self.__localSharedLibs = localSharedLibs
self.__externalLibs = externalLibs
self.__localDir = os.getcwd()
@property
def installDir(self):
assert False
@property
def target(self):
assert False
@property
def env(self):
return self.defaultEnv
@property
def defaultEnv(self):
return self.__env.defaultEnv
@property
def swigEnv(self):
return self.__env.swigEnv
@property
def srcDir(self):
return self.__env.srcDir
@property
def buildDir(self):
return self.__env.buildDir
@property
def binDir(self):
return self.__env.binDir
@property
def libDir(self):
return self.__env.libDir
@property
def libPyDir(self):
return self.__env.libPyDir
@property
def testDir(self):
return self.__env.testDir
@property
def etcDir(self):
return self.__env.etcDir
@property
def isWindows(self):
return self.__env.isWindows
@property
def isLinux(self):
return self.__env.isLinux
@property
def isClean(self):
return self.__env.isClean
@property
def name(self):
return self.__name
@property
def sources(self):
return self.__sources
@property
def cppFlags(self):
return self.env['CPPFLAGS']
@property
def linkFlags(self):
return self.env['LINKFLAGS']
@property
def cppDefines(self):
return self.env['CPPDEFINES'].copy()
@property
def localSharedLibsNames(self):
return self.__localSharedLibs
@property
def externalLibs(self):
return self.__externalLibs
@property
def localDir(self):
return self.__localDir
@property
def externalLibsNames(self):
nameList = []
for externalLib in self.externalLibs:
nameList += externalLib.lib
return nameList
@property
def externalLibsPaths(self):
return [lib.libPath for lib in self.externalLibs if lib.libPath]
@property
def externalLibsIncludes(self):
return [lib.include for lib in self.externalLibs if lib.include]
def absPath(self, path):
return os.path.abspath(path)
def dirName(self, path):
return os.path.dirname(path)
def join(self, *paths):
return os.path.join(*paths)
def isFile(self, fileNamePath):
return os.path.isfile(fileNamePath)
def clean(self, fileNamePath):
if not all([self.isClean, self.isFile(fileNamePath)]):
return
os.remove(fileNamePath)
print('Removed', fileNamePath)
def summary(self):
lstr = self.name + '\n'
return lstr

View File

@@ -0,0 +1,78 @@
#
# This file is part of cpp-patterns.
#
# cpp-patterns is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cpp-patterns is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cpp-patterns. If not, see <http://www.gnu.org/licenses/>.
#
from .LocalTarget import LocalTarget
class RunableTarget(LocalTarget):
def __init__(
self, env, name, sources, localStaticLibs, localSharedLibs, externalLibs
):
super(RunableTarget, self).__init__(
env, name, sources, localStaticLibs, localSharedLibs, externalLibs
)
@property
def scriptFileDir(self):
assert False
def getScriptFilePath(self):
import os
scriptFileDir = self.scriptFileDir
if not os.path.exists(scriptFileDir):
os.makedirs(scriptFileDir)
if self.isLinux:
return os.path.join(scriptFileDir, self.name) + '.sh'
elif self.isWindows:
return os.path.join(scriptFileDir, self.name) + '.exe.bat'
def _writeLinuxScript(self):
scriptPath = self.getScriptFilePath()
self.clean(scriptPath)
if all([not self.isClean, not self.isFile(scriptPath)]):
print('Writing', scriptPath)
with open(scriptPath, 'w') as f:
f.write(r'#!/bin/sh' + '\n')
f.write(r'SCRIPT=`realpath -s $0`' + '\n')
f.write(r'SCRIPTPATH=`dirname $SCRIPT`' + '\n')
f.write(
r'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:' + self.libDir +
'\n'
)
f.write(r'$SCRIPTPATH/' + self.name + r' "$@"')
import os
os.system('chmod +x ' + scriptPath)
def _writeWindowsScript(self):
scriptPath = self.getScriptFilePath()
self.clean(scriptPath)
if all([not self.isClean, not self.isFile(scriptPath)]):
print('Writing', scriptPath)
with open(scriptPath, 'w') as f:
f.write(r'@echo off' + '\n')
f.write(r'setlocal' + '\n')
f.write(r'set scriptPath=%~dp0' + '\n')
f.write(r'PATH=$PATH;' + self.libDir + '\n')
f.write(r'%scriptPath%' + self.name + r' %*')
def writeScript(self):
if self.isLinux:
return self._writeLinuxScript()
elif self.isWindows:
return self._writeWindowsScript()

View File

@@ -0,0 +1,18 @@
#
# This file is part of cpp-patterns.
#
# cpp-patterns is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cpp-patterns is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cpp-patterns. If not, see <http://www.gnu.org/licenses/>.
#
from .Executable import Executable

View File

@@ -0,0 +1,95 @@
#
# This file is part of cpp-patterns.
#
# cpp-patterns is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cpp-patterns is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cpp-patterns. If not, see <http://www.gnu.org/licenses/>.
#
import os
import platform
import sys
import SCons
class Architecture(object):
def __init__(self):
self.__osName = platform.system()
self.__pythonVersion = platform.python_version()
self.__sconsVersion = SCons.__version__
if self.__osName not in self.supportedSystems:
raise RuntimeError('Unsupported OS architecture.')
self.__sysDirName = 'unknown'
if self.isLinux:
self.__sysDirName = 'linx64'
if not 'LD_LIBRARY_PATH' in os.environ:
os.environ['LD_LIBRARY_PATH'] = ''
elif self.isWindows:
self.__sysDirName = 'winx64'
@property
def supportedSystems(self):
return ['Windows', 'Linux']
@property
def osName(self):
return self.__osName
@property
def isWindows(self):
return self.osName == 'Windows'
@property
def isLinux(self):
return self.osName == 'Linux'
@property
def pythonVersion(self):
return self.__pythonVersion
@property
def sconsVersion(self):
return self.__sconsVersion
@property
def sysDirName(self):
return self.__sysDirName
def _getFormatedPaths(self, pathStr):
return str(pathStr.split(os.pathsep)).replace(', ', ',\n').replace(
'[', '[\n'
).replace(']', '\n]')
def summary(self):
lstr = '=' * 50 + '\n'
lstr += 'Architecture Summary\n'
lstr += '=' * 50 + '\n'
lstr += 'operating system: ' + self.osName + '\n'
lstr += 'python version: ' + self.pythonVersion + '\n'
lstr += 'scons version: ' + self.sconsVersion + '\n'
lstr += 'path: ' + \
self._getFormatedPaths(os.environ['PATH']) + '\n'
if self.isLinux:
lstr += 'LD_LIBRARY_PATH: ' + \
self._getFormatedPaths(os.environ['LD_LIBRARY_PATH']) + '\n'
if os.environ.get('PYTHONPATH'):
lstr += 'python path: ' + \
self._getFormatedPaths(os.environ['PYTHONPATH']) + '\n'
lstr += 'session python path: ' + \
self._getFormatedPaths(os.pathsep.join(sys.path)) + '\n'
lstr += '-' * 50 + '\n'
return lstr

View File

@@ -0,0 +1,66 @@
#
# This file is part of cpp-patterns.
#
# cpp-patterns is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cpp-patterns is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cpp-patterns. If not, see <http://www.gnu.org/licenses/>.
#
class ArgumentsSetup(object):
def __init__(self):
from SCons.Script import ARGUMENTS, GetOption
self.__debugArg = ARGUMENTS.get('DEBUG', '1')
if self.__debugArg not in ['0', '1']:
raise RuntimeError('Check the DEBUG input argument.')
self.__assertArg = '1' if self.__debugArg == '1' else '0'
if self.__assertArg not in ['0', '1']:
raise RuntimeError('Check the ASSERT input argument.')
self.__compilerName = ARGUMENTS.get('COMPILER', '')
self.__isClean = GetOption('clean')
@property
def isDebug(self):
return self.__debugArg == '1'
@property
def isAssert(self):
return self.__assertArg == '1'
@property
def compilerName(self):
return self.__compilerName
@property
def isClean(self):
return self.__isClean
def summary(self):
def printDefault(x):
return x if x else '-default-'
lstr = '=' * 50 + '\n'
lstr += 'Build Arguments Summary\n'
lstr += '=' * 50 + '\n'
lstr += 'debug: ' + str(self.isDebug) + '\n'
lstr += 'assert: ' + str(self.isAssert) + '\n'
lstr += 'compiler name: ' + printDefault(self.compilerName) + '\n'
lstr += 'clean build: ' + str(self.isClean) + '\n'
lstr += '-' * 50 + '\n'
return lstr

View File

@@ -0,0 +1,162 @@
#
# This file is part of cpp-patterns.
#
# cpp-patterns is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cpp-patterns is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cpp-patterns. If not, see <http://www.gnu.org/licenses/>.
#
class BuildPath(object):
def __init__(self, archObj, argObj):
import os
from SCons.Script import Dir
# main
self.__srcDir = Dir('#').abspath
self.__projectDir = os.path.abspath(os.path.join(self.__srcDir, '..'))
self.__runtimeDir = os.path.join(self.__projectDir, 'runtime')
self.__thirdpartyDir = os.path.join(self.__projectDir, 'thirdparty')
#assert os.path.exists(self.__runtimeDir)
#assert os.path.exists(self.__thirdpartyDir)
def _exist(path):
if not os.path.exists(path):
os.makedirs(path)
return path
# build variables
self.__buildDir = os.path.join(
self.__projectDir, 'build', archObj.sysDirName
)
self.__installDir = os.path.join(
self.__projectDir, 'install', archObj.sysDirName
)
self.__buildDir = _exist(self.__buildDir)
self.__binDir = _exist(os.path.join(self.__installDir, 'bin'))
self.__libDir = _exist(os.path.join(self.__installDir, 'lib'))
self.__libPyDir = _exist(os.path.join(self.__libDir, 'py'))
self.__testDir = _exist(os.path.join(self.__installDir, 'test'))
self.__etcDir = _exist(os.path.join(self.__installDir, 'etc'))
# lib
self.__runtimeArchDir = os.path.join(
self.__runtimeDir, archObj.sysDirName
)
#assert os.path.exists(self.__runtimeArchDir)
# thirdparty
__thirdpartyNoArchDir = os.path.join(self.__thirdpartyDir, 'noarch')
__thirdpartyArchDir = os.path.join(
self.__thirdpartyDir, archObj.sysDirName
)
self.__thirdpartyNoArchBinDir = os.path.join(
__thirdpartyNoArchDir, 'bin'
)
self.__thirdpartyArchBinDir = os.path.join(__thirdpartyArchDir, 'bin')
#assert os.path.exists(self.__thirdpartyNoArchBinDir)
#assert os.path.exists(self.__thirdpartyArchBinDir)
self.__thirdpartyNoArchIncludeDir = os.path.join(
__thirdpartyNoArchDir, 'include'
)
self.__thirdpartyArchIncludeDir = os.path.join(
__thirdpartyArchDir, 'include'
)
#assert os.path.exists(self.__thirdpartyNoArchIncludeDir)
#assert os.path.exists(self.__thirdpartyArchIncludeDir)
self.__thirdpartyNoArchLibDir = os.path.join(
__thirdpartyNoArchDir, 'lib'
)
self.__thirdpartyArchLibDir = os.path.join(__thirdpartyArchDir, 'lib')
#assert os.path.exists(self.__thirdpartyNoArchLibDir)
#assert os.path.exists(self.__thirdpartyArchLibDir)
self.__thirdpartyNoArchLibPyDir = os.path.join(
self.__thirdpartyNoArchLibDir, 'py'
)
#assert os.path.exists(self.__thirdpartyNoArchLibPyDir)
@property
def projectDir(self):
return self.__projectDir
@property
def srcDir(self):
return self.__srcDir
@property
def buildDir(self):
return self.__buildDir
@property
def binDir(self):
return self.__binDir
@property
def libDir(self):
return self.__libDir
@property
def libPyDir(self):
return self.__libPyDir
@property
def testDir(self):
return self.__testDir
@property
def etcDir(self):
return self.__etcDir
@property
def runtimeArchDir(self):
return self.__runtimeArchDir
@property
def thirdpartyNoArchIncludeDir(self):
return self.__thirdpartyNoArchIncludeDir
@property
def thirdpartyArchIncludeDir(self):
return self.__thirdpartyArchIncludeDir
@property
def thirdpartyArchLibDir(self):
return self.__thirdpartyArchLibDir
def summary(self):
lstr = '=' * 50 + '\n'
lstr += 'Paths Summary\n'
lstr += '=' * 50 + '\n'
lstr += 'project: ' + self.projectDir + '\n'
lstr += 'build: ' + self.buildDir + '\n'
lstr += 'install bin: ' + self.binDir + '\n'
lstr += 'install lib: ' + self.libDir + '\n'
lstr += 'install py: ' + self.libPyDir + '\n'
lstr += 'install test: ' + self.testDir + '\n'
lstr += 'install etc: ' + self.etcDir + '\n'
lstr += 'runtime: ' + self.runtimeArchDir + '\n'
lstr += 'thirdparty noarch include: ' + self.thirdpartyNoArchIncludeDir + '\n'
lstr += 'thirdparty arch include: ' + self.thirdpartyArchIncludeDir + '\n'
lstr += 'thirdparty arch lib: ' + self.thirdpartyArchLibDir + '\n'
lstr += '-' * 50 + '\n'
return lstr

View File

@@ -0,0 +1,243 @@
#
# This file is part of cpp-patterns.
#
# cpp-patterns is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cpp-patterns is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cpp-patterns. If not, see <http://www.gnu.org/licenses/>.
#
class CompilerSetup(object):
def __init__(self, archObj, argObj):
self.__archObj = archObj
self.__argObj = argObj
self.__gccCom = 'gcc'
self.__intelCom = 'intel'
self.__clangCom = 'clang'
self.__msvcCom = 'msvc'
if archObj.isLinux:
self.__defaultCompiler = self.__gccCom
self.__compilers = {
self.__gccCom: ['gcc', 'g++'],
self.__intelCom: ['ic', 'icpc'],
self.__clangCom: ['clang', 'clang++']
}
elif archObj.isWindows:
self.__defaultCompiler = self.__msvcCom
self.__compilers = {
self.__msvcCom: ['cl', 'cl'],
self.__intelCom: ['ic', 'icpp'],
self.__clangCom: ['clang', 'clang++']
}
self.__compiler = argObj.compilerName if argObj.compilerName else \
self.__defaultCompiler
if self.__compiler not in self.__compilers:
raise RuntimeError('Check the COMPILER input argument.')
#
# widnows compilers
#
def _clang_windows(self):
return dict(
ccFlags=["-std=c++1z", '-fms-compatibility-version=21'],
optCFlags=["-O3"],
optLinkFlags=["-Wl,--export-dynamic"],
debugCFlags=[
"-O0", "-Wall", "-Wuninitialized", "-Wunused", "-Wconversion",
"-fpermissive"
],
debugLinkFlags=["-g"],
profileCFlags=["-g"],
profileLinkFlags=["-g"],
ompCFlags=["-fopenmp"],
ompLinkFlags=["-fopenmp"],
defFlagsStr="-D",
includeFlagsStr="-I"
)
def _intel_windows(self):
return dict(
ccFlags=["/MD", "/EHsc", "/Qvc10"],
optCFlags=[
"/O3", "/Qrestrict", "/Qprec-div-", "/Qvec-report0", "/Qip"
], # last not profile only
optLinkFlags=["/MANIFEST"],
debugCFlags=[
"/Zi", "/Qrestrict", "/Fd${TARGET}.pdb", "/Od", "/W3", "/Wcheck"
],
debugLinkFlags=["/debug"],
profileCFlags=["/Zi", "/Fd${TARGET}.pdb", "/Qprof-gen-"],
profileLinkFlags=["/debug"],
ompCFlags=["/Qopenmp"],
ompLinkFlags=[""],
defFlagsStr="/D",
includeFlagsStr="/I"
)
def _msvc_windows(self):
return dict(
ccFlags=["/MD", "/EHsc", "/wd4251"],
optCFlags=["/O2"],
optLinkFlags=["/MANIFEST"],
debugCFlags=["/Od", "/Zi", "/Fd${TARGET}.pdb", "/W3"],
debugLinkFlags=["/debug"],
profileCFlags=["/Zi", "/Fd${TARGET}.pdb"],
profileLinkFlags=["/debug"],
ompCFlags=["/openmp"],
ompLinkFlags=[""],
defFlagsStr="/D",
includeFlagsStr="/I"
)
#
# linux compilers
#
def _clang_linux(self):
return dict(
ccFlags=["-std=c++1z"],
optCFlags=["-O3"],
optLinkFlags=["-Wl,--export-dynamic"],
debugCFlags=[
"-g", "-O0", "-Wall", "-Wuninitialized", "-Wunused",
"-Wconversion", "-fpermissive"
],
debugLinkFlags=["-g"],
profileCFlags=["-g"],
profileLinkFlags=["-g"],
ompCFlags=["-fopenmp"],
ompLinkFlags=["-fopenmp"],
defFlagsStr="-D",
includeFlagsStr="-I"
)
def _intel_linux(self):
return dict(
ccFlags=["-Wcheck"],
optCFlags=["-O3", "-no-prec-div", "-ip", "-qopt-report"],
optLinkFlags=["-O3"],
debugCFlags=["-g", "-O0", "-Wall"],
debugLinkFlags=["-g", "-O0"],
profileCFlags=["-g"],
profileLinkFlags=["-g"],
ompCFlags=["-openmp"],
ompLinkFlags=["-openmp"],
defFlagsStr="-D",
includeFlagsStr="-I"
)
def _gcc_linux(self):
return dict(
ccFlags=["-std=c++1z"],
optCFlags=["-O3"],
optLinkFlags=["-Wl,--export-dynamic"],
debugCFlags=[
"-g", "-O0", "-Wall", "-Wuninitialized", "-Wunused",
"-Wconversion", "-fpermissive", "-Wimplicit-fallthrough"
],
debugLinkFlags=["-g"],
profileCFlags=["-g"],
profileLinkFlags=["-g"],
ompCFlags=["-fopenmp"],
ompLinkFlags=["-fopenmp"],
defFlagsStr="-D",
includeFlagsStr="-I"
)
def _arch_compiler_flags(self):
if self.__archObj.isLinux:
if self.__compiler == self.__gccCom:
return self._gcc_linux()
elif self.__compiler == self.__intelCom:
return self._intel_linux()
elif self.__compiler == self.__clangCom:
return self._clang_linux()
elif self.__archObj.isWindows:
retDict = None
if self.__compiler == self.__msvcCom:
retDict = self._msvc_windows()
elif self.__compiler == self.__intelCom:
retDict = self._intel_windows()
elif self.__compiler == self.__clangCom:
retDict = self._clang_windows()
return retDict
@property
def compilers(self):
return self.__compilers
@property
def defaultCompiler(self):
return self.__defaultCompiler
@property
def compiler(self):
return self.__compiler
@property
def cCompiler(self):
return self.__compilers[self.compiler][0]
@property
def cppCompiler(self):
return self.__compilers[self.compiler][1]
def getFlags(self):
__buildFlags = []
__linkFlags = []
__archFlags = self._arch_compiler_flags()
__buildFlags += __archFlags['ccFlags']
if self.__argObj.isDebug:
__buildFlags += __archFlags['debugCFlags']
__linkFlags += __archFlags['debugLinkFlags']
else:
__buildFlags += __archFlags['optCFlags']
__linkFlags += __archFlags['optLinkFlags']
__localDefs = {}
if not self.__argObj.isAssert:
__localDefs['NDEBUG'] = None
if self.__archObj.isWindows:
#__localDefs['BOOST_LIB_TOOLSET'] = 'vc141'
__localDefs['BOOST_ALL_DYN_LINK'] = None
#__localDefs['BOOST_LIB_DIAGNOSTIC'] = None
return dict(
buildFlags=__buildFlags,
linkFlags=__linkFlags,
localDefs=__localDefs,
defFlagsStr=__archFlags['defFlagsStr'],
includeFlagsStr=__archFlags['includeFlagsStr']
)
def summary(self):
__archFlags = self.getFlags()
lstr = '=' * 50 + '\n'
lstr += 'Compiler Configuration Summary\n'
lstr += '=' * 50 + '\n'
lstr += 'system compilers: ' + str(self.compilers) + '\n'
lstr += 'default compiler: ' + self.defaultCompiler + '\n'
lstr += 'selected compiler: ' + self.compiler + '\n'
lstr += 'build flags: ' + str(__archFlags['buildFlags']) + '\n'
lstr += 'link flags: ' + str(__archFlags['linkFlags']) + '\n'
lstr += 'def flags: ' + str(__archFlags['localDefs']) + '\n'
lstr += '-' * 50 + '\n'
return lstr

View File

@@ -0,0 +1,253 @@
#
# This file is part of cpp-patterns.
#
# cpp-patterns is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cpp-patterns is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cpp-patterns. If not, see <http://www.gnu.org/licenses/>.
#
import os
from SCons.Script import (Environment, Alias, Default, VariantDir, SConscript)
from localtargets import Executable as LocalExecutable
class CustomBuildEnvironment(object):
def __init__(self):
from .Architecture import Architecture
from .ArgumentsSetup import ArgumentsSetup
from .CompilerSetup import CompilerSetup
from .BuildPath import BuildPath
from .NamedObjectTable import NamedObjectTable
self.__archConfig = Architecture()
self.__argumentsConfig = ArgumentsSetup()
self.__compilerConfig = CompilerSetup(
self.__archConfig, self.__argumentsConfig
)
self.__pathConfig = BuildPath(self.__archConfig, self.__argumentsConfig)
additionalEnv = dict(
tools=[
'default',
]
)
self.__defaultEnv = Environment(ENV=os.environ, **additionalEnv)
buildAndLinkFlags = self.__compilerConfig.getFlags()
self.__defaultEnv.Replace(
CC=self.__compilerConfig.cCompiler,
CXX=self.__compilerConfig.cppCompiler
)
self.__defaultEnv['CPPFLAGS'] = buildAndLinkFlags['buildFlags']
self.__defaultEnv['LINKFLAGS'] = buildAndLinkFlags['linkFlags']
self.__defaultEnv['CPPDEFINES'] = buildAndLinkFlags['localDefs']
self.__defaultEnv['CPPDEFPREFIX'] = buildAndLinkFlags['defFlagsStr']
self.__defaultEnv['INCPREFIX'] = buildAndLinkFlags['includeFlagsStr']
self.__defaultEnv['CPPPATH'] = [
self.__pathConfig.srcDir,
self.__pathConfig.thirdpartyNoArchIncludeDir,
self.__pathConfig.thirdpartyArchIncludeDir,
]
self.__defaultEnv['LIBPATH'] = [self.__pathConfig.libDir]
'''
self.__defaultEnv['_MSVC_OUTPUT_FLAG'] = '-o $TARGET'
self.__defaultEnv['CCCOM'] = self.__defaultEnv['CCCOM'].replace('/c', '-c')
self.__defaultEnv['CXXCOM'] = self.__defaultEnv['CXXCOM'].replace('/c', '-c')
self.__defaultEnv['SHCCCOM'] = self.__defaultEnv['SHCCCOM'].replace('/c', '-c')
self.__defaultEnv['SHCXXCOM'] = self.__defaultEnv['SHCXXCOM'].replace('/c', '-c')
self.__defaultEnv['CCFLAGS'].remove('/nologo')
self.__defaultEnv['CXXFLAGS'].remove('/TP')
'''
Alias('installBin', self.__pathConfig.binDir)
Alias('installLib', self.__pathConfig.libDir)
Alias('installLibPy', self.__pathConfig.libPyDir)
Alias('installTest', self.__pathConfig.testDir)
Alias('installEtc', self.__pathConfig.etcDir)
Alias(
'install', [
'installBin', 'installLib', 'installLibPy',
'installTest', 'installEtc'
]
)
Default('install')
'''
open('defaultEnv.txt', 'w').write(self.__defaultEnv.Dump())
'''
self.__localTargets = {
name: NamedObjectTable(tableName=title)
for name, title in [
('program', 'Programs'),
]
}
if self.isLinux:
pass #self.defaultEnv.Install(self.libDir, self.runtimeArchDir)
@property
def SConscript(self):
return 'SConscript'
@property
def defaultEnv(self):
return self.__defaultEnv
@property
def swigEnv(self):
return self.__swigEnv
@property
def srcDir(self):
return self.__pathConfig.srcDir
@property
def startDir(self):
return self.__pathConfig.startDir
@property
def cppDir(self):
return self.__pathConfig.cppDir
@property
def buildDir(self):
return self.__pathConfig.buildDir
@property
def binDir(self):
return self.__pathConfig.binDir
@property
def libDir(self):
return self.__pathConfig.libDir
@property
def libPyDir(self):
return self.__pathConfig.libPyDir
@property
def testDir(self):
return self.__pathConfig.testDir
@property
def etcDir(self):
return self.__pathConfig.etcDir
@property
def runtimeArchDir(self):
return self.__pathConfig.runtimeArchDir
@property
def thirdpartyArchLibDir(self):
return self.__pathConfig.thirdpartyArchLibDir
@property
def thirdpartyLibsPyDir(self):
return self.__pathConfig.thirdpartyLibsPyDir
@property
def isWindows(self):
return self.__archConfig.isWindows
@property
def isLinux(self):
return self.__archConfig.isLinux
@property
def isClean(self):
return self.__argumentsConfig.isClean
def _checkSources(self, sources, isShared=False):
if isinstance(sources, str):
sources = [sources]
assert isinstance(sources, list)
# sources = list(set(sources))
newSources = []
for src in sources:
if '.proto' in src:
protoObj = self.__localTargets['proto'].get(
[src.replace('.proto', '')]
)[0]
for ccSrc in protoObj.getCC():
newSources.append(
self.defaultEnv.SharedObject(ccSrc)
if isShared else self.defaultEnv.Object(ccSrc)
)
else:
newSources.append(src)
return newSources
def program(
self,
targetName,
sources,
localStaticLibs=[],
localSharedLibs=[],
externalLibs=[],
isBin=False
):
sources = self._checkSources(sources)
progObj = LocalExecutable(
env=self,
name=targetName,
sources=sources,
localStaticLibs=localStaticLibs,
localSharedLibs=localSharedLibs,
externalLibs=[],#self.__externalLibTable.get(externalLibs),
isBin=isBin
)
self.__localTargets['program'].register(progObj)
return progObj
def _buildSConscript(self):
def _getRootList():
for root, _, files in os.walk(self.srcDir):
if self.SConscript in files:
yield root.replace(self.srcDir, self.buildDir)
for root in _getRootList():
SConscript(
os.path.join(root, self.SConscript), exports={
'env': self
}
)
def build(self):
VariantDir(variant_dir=self.buildDir, src_dir=self.srcDir, duplicate=0)
self._buildSConscript()
print(self.summary())
def summary(self):
lstr = self.__archConfig.summary()
lstr += self.__argumentsConfig.summary()
lstr += self.__compilerConfig.summary()
lstr += self.__pathConfig.summary()
for name in sorted(list(self.__localTargets.keys())):
lstr += self.__localTargets[name].summary()
return lstr

View File

@@ -0,0 +1,52 @@
#
# This file is part of cpp-patterns.
#
# cpp-patterns is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cpp-patterns is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cpp-patterns. If not, see <http://www.gnu.org/licenses/>.
#
class NamedObjectTable(object):
def __init__(self, tableName):
self.__name = tableName
self.__list = {}
@property
def name(self):
return self.__name
def register(self, namedObj):
self.__list[namedObj.name] = namedObj
def get(self, objNames):
keys = list(self.__list.keys())
namedObjs = []
for objName in objNames:
if objName in keys:
namedObjs.append(self.__list[objName])
else:
raise RuntimeError('Unknown ' + self.name + ': ' + objName)
return namedObjs
def iterObjects(self):
return iter(list(self.__list.values()))
def summary(self):
lstr = '=' * 50 + '\n'
lstr += self.name + ' Summary\n'
lstr += '=' * 50 + '\n'
for namedObj in list(self.__list.values()):
lstr += namedObj.summary() + '-' * 50 + '\n'
return lstr

View File

@@ -0,0 +1,18 @@
#
# This file is part of cpp-patterns.
#
# cpp-patterns is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cpp-patterns is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cpp-patterns. If not, see <http://www.gnu.org/licenses/>.
#
from .CustomBuildEnvironment import CustomBuildEnvironment

View File

@@ -0,0 +1,16 @@
#
# This file is part of cpp-patterns.
#
# cpp-patterns is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cpp-patterns is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cpp-patterns. If not, see <http://www.gnu.org/licenses/>.
#