Improve nested lookup for libraries

This commit is contained in:
Ivan Kravets
2014-08-02 20:47:05 +03:00
parent ce0c1f9f4a
commit 47edfdb043
4 changed files with 63 additions and 48 deletions

View File

@ -99,13 +99,13 @@ env.Append(
)
)
BUILT_LIBS = env.ProcessGeneral()
CORELIBS = env.ProcessGeneral()
#
# Target: Build executable and linkable firmware
#
target_elf = env.BuildFirmware(BUILT_LIBS + ["m"])
target_elf = env.BuildFirmware(CORELIBS + ["m"])
#
# Target: Extract EEPROM data (from EEMEM directive) to .eep file

View File

@ -75,13 +75,13 @@ env.Append(
)
)
BUILT_LIBS = env.ProcessGeneral()
CORELIBS = env.ProcessGeneral()
#
# Target: Build executable and linkable firmware
#
target_elf = env.BuildFirmware(BUILT_LIBS + ["m"])
target_elf = env.BuildFirmware(CORELIBS + ["m"])
#
# Target: Build the .hex

View File

@ -89,13 +89,13 @@ env.Append(
)
)
BUILT_LIBS = env.ProcessGeneral()
CORELIBS = env.ProcessGeneral()
#
# Target: Build executable and linkable firmware
#
target_elf = env.BuildFirmware(BUILT_LIBS + ["c", "gcc", "m"])
target_elf = env.BuildFirmware(CORELIBS + ["c", "gcc", "m"])
#
# Target: Build the .bin file

View File

@ -9,7 +9,7 @@ from SCons.Script import SConscript, SConscriptChdir
def ProcessGeneral(env):
libs = []
corelibs = []
if "BUILD_FLAGS" in env:
env.MergeFlags(env['BUILD_FLAGS'])
@ -20,55 +20,28 @@ def ProcessGeneral(env):
if "FRAMEWORK" in env:
SConscriptChdir(0)
libs = SConscript(env.subst(join("$PIOBUILDER_DIR", "scripts",
"frameworks", "${FRAMEWORK}.py")),
exports="env")
return libs
corelibs = SConscript(env.subst(join("$PIOBUILDER_DIR", "scripts",
"frameworks", "${FRAMEWORK}.py")),
exports="env")
return corelibs
def BuildLibrary(env, variant_dir, library_dir):
lib = env.Clone()
vdirs = lib.VariantDirRecursive(variant_dir, library_dir)
return lib.Library(
lib.subst(variant_dir),
[lib.GlobCXXFiles(vdir) for vdir in vdirs]
)
def BuildDependentLibraries(env, src_dir):
libs = []
for deplibfile in env.GetDependentLibraries(src_dir):
for lsd_dir in env['LIBSOURCE_DIRS']:
lsd_dir = env.subst(lsd_dir)
if not isdir(lsd_dir):
continue
for libname in listdir(lsd_dir):
if not isfile(join(lsd_dir, libname, deplibfile)):
continue
_libbuild_dir = join("$BUILD_DIR", libname)
env.Append(CPPPATH=[_libbuild_dir])
libs.append(
env.BuildLibrary(_libbuild_dir, join(lsd_dir, libname)))
return libs
def BuildFirmware(env, libslist):
def BuildFirmware(env, corelibs):
src = env.Clone()
vdirs = src.VariantDirRecursive(
join("$BUILD_DIR", "src"), join("$PROJECT_DIR", "src"))
# build source's dependent libs
deplibs = []
for vdir in vdirs:
_libs = src.BuildDependentLibraries(vdir)
if _libs:
libslist += _libs
deplibs += src.BuildDependentLibraries(vdir)
src.MergeFlags(getenv("PIOSRCBUILD_FLAGS", "$SRCBUILD_FLAGS"))
return src.Program(
join("$BUILD_DIR", "firmware"),
[src.GlobCXXFiles(vdir) for vdir in vdirs],
LIBS=libslist,
LIBS=deplibs + corelibs,
LIBPATH="$BUILD_DIR",
PROGSUFFIX=".elf")
@ -82,12 +55,53 @@ def GlobCXXFiles(env, path):
return files
def BuildLibrary(env, variant_dir, library_dir):
lib = env.Clone()
vdirs = lib.VariantDirRecursive(variant_dir, library_dir)
return lib.Library(
lib.subst(variant_dir),
[lib.GlobCXXFiles(vdir) for vdir in vdirs]
)
def BuildDependentLibraries(env, src_dir):
libs = []
deplibs = env.GetDependentLibraries(src_dir)
env.Append(CPPPATH=[join("$BUILD_DIR", l) for (l, _) in deplibs])
for (libname, lsd_dir) in deplibs:
libs.append(
env.BuildLibrary(join("$BUILD_DIR", libname), join(lsd_dir,
libname)))
return libs
def GetDependentLibraries(env, src_dir):
deplibs = []
regexp = re.compile(r"^#include\s+<([^>]+)>", re.M)
includes = {}
regexp = re.compile(r"^\s?#include\s+(?:\<|\"|\')([^\>\"\']+)(?:\>|\"|\')",
re.M)
for node in env.GlobCXXFiles(src_dir):
deplibs += regexp.findall(node.get_text_contents())
return deplibs
env.ParseIncludesRecurive(regexp, node, includes)
includes = sorted(includes.items(), key=lambda s: s[0])
return set([(i[1][1], i[1][2]) for i in includes])
def ParseIncludesRecurive(env, regexp, source_file, includes):
matches = regexp.findall(source_file.get_text_contents())
for inc_name in matches:
if inc_name in includes:
continue
for lsd_dir in env['LIBSOURCE_DIRS']:
lsd_dir = env.subst(lsd_dir)
if not isdir(lsd_dir):
continue
for libname in listdir(lsd_dir):
inc_path = join(lsd_dir, libname, inc_name)
if not isfile(inc_path):
continue
includes[inc_name] = (len(includes) + 1, libname, lsd_dir)
env.ParseIncludesRecurive(regexp, env.File(inc_path), includes)
def VariantDirRecursive(env, variant_dir, src_dir, duplicate=True):
@ -141,11 +155,12 @@ def exists(_):
def generate(env):
env.AddMethod(ProcessGeneral)
env.AddMethod(BuildLibrary)
env.AddMethod(BuildDependentLibraries)
env.AddMethod(BuildFirmware)
env.AddMethod(GlobCXXFiles)
env.AddMethod(BuildLibrary)
env.AddMethod(BuildDependentLibraries)
env.AddMethod(GetDependentLibraries)
env.AddMethod(ParseIncludesRecurive)
env.AddMethod(VariantDirRecursive)
env.AddMethod(ParseBoardOptions)
return env