diff --git a/platformio/builder/main.py b/platformio/builder/main.py index 00d0d0d0..8b5565c5 100644 --- a/platformio/builder/main.py +++ b/platformio/builder/main.py @@ -9,46 +9,51 @@ from SCons.Script import (DefaultEnvironment, Exit, SConscript, from platformio.util import get_home_dir, get_project_dir, get_source_dir -PIOBUILDER_DIR = join(get_source_dir(), "builder") # AllowSubstExceptions() -# define user's variables -clivars = Variables(None) -clivars.AddVariables( +# allow common variables from INI file +commonvars = Variables(None) +commonvars.AddVariables( ("PIOENV",), ("PLATFORM",), - ("BOARD",), - ("UPLOAD_PORT",) -) + ("FRAMEWORK",), -# print sdf + # board options + ("BOARD",), + ("BOARD_MCU",), + ("BOARD_F_CPU",), + + # upload options + ("UPLOAD_PORT",), + ("UPLOAD_PROTOCOL",), + ("UPLOAD_SPEED",) +) DefaultEnvironment( tools=["default", "platformio"], - toolpath=[join(PIOBUILDER_DIR, "tools")], - variables=clivars, + toolpath=[join("$PIOBUILDER_DIR", "tools")], + variables=commonvars, + PIOBUILDER_DIR=join(get_source_dir(), "builder"), PROJECT_DIR=get_project_dir(), PLATFORMIOHOME_DIR=get_home_dir(), - PLATFORM_DIR=join("$PLATFORMIOHOME_DIR", "${PLATFORM}"), - PLATFORMCORE_DIR=join("$PLATFORM_DIR", "core"), + PLATFORM_DIR=join("$PLATFORMIOHOME_DIR", "$PLATFORM"), + PLATFORMFW_DIR=join("$PLATFORM_DIR", "frameworks", "$FRAMEWORK"), PLATFORMTOOLS_DIR=join("$PLATFORM_DIR", "tools"), - BUILD_DIR=join("$PROJECT_DIR", ".pioenvs", "${PIOENV}"), - BUILDCORE_DIR=join("$BUILD_DIR", "core"), - BUILDSRC_DIR=join("$BUILD_DIR", "src") + BUILD_DIR=join("$PROJECT_DIR", ".pioenvs", "$PIOENV") ) -PLATFORM = DefaultEnvironment().subst("${PLATFORM}") +env = DefaultEnvironment() -if not isdir(DefaultEnvironment().subst("$PLATFORMIOHOME_DIR")): - Exit("You haven't installed any platforms yet. Please use" +if not isdir(env['PLATFORMIOHOME_DIR']): + Exit("You haven't installed any platforms yet. Please use " "`platformio install` command") -elif not isdir(DefaultEnvironment().subst("$PLATFORM_DIR")): +elif not isdir(env.subst("$PLATFORM_DIR")): Exit("An '%s' platform hasn't been installed yet. Please use " - "`platformio install %s` command" % (PLATFORM.upper(), - PLATFORM)) + "`platformio install %s` command" % (env['PLATFORM'].upper(), + env['PLATFORM'])) SConscriptChdir(0) -SConscript(join(PIOBUILDER_DIR, "scripts", PLATFORM + ".py")) +SConscript(env.subst(join("$PIOBUILDER_DIR", "scripts", "${PLATFORM}.py"))) diff --git a/platformio/builder/scripts/atmelavr.py b/platformio/builder/scripts/atmelavr.py index a1185a5c..cd2492c1 100644 --- a/platformio/builder/scripts/atmelavr.py +++ b/platformio/builder/scripts/atmelavr.py @@ -3,32 +3,18 @@ """ Builder for Atmel AVR series of microcontrollers - - Fully compatible with Arduino programming language (based on Wiring) """ from os.path import join from SCons.Script import (AlwaysBuild, Builder, COMMAND_LINE_TARGETS, Default, - DefaultEnvironment, Exit) + DefaultEnvironment, Exit, SConscript, + SConscriptChdir) -# -# SETUP ENVIRONMENT -# env = DefaultEnvironment() -BOARD_OPTIONS = env.ParseBoardOptions(join("$PLATFORM_DIR", "boards.txt"), - "${BOARD}") env.Replace( - ARDUINO_VERSION=open(join(env.subst("$PLATFORM_DIR"), - "version.txt")).read().replace(".", "").strip(), - - BOARD_MCU=BOARD_OPTIONS['build.mcu'], - BOARD_F_CPU=BOARD_OPTIONS['build.f_cpu'], - BOARD_VID=BOARD_OPTIONS.get("build.vid", "0"), - BOARD_PID=BOARD_OPTIONS.get("build.pid", "0"), - AR="avr-ar", AS="avr-as", CC="avr-gcc", @@ -42,38 +28,24 @@ env.Replace( "-g", # include debugging info (so errors include line numbers) "-x", "assembler-with-cpp", "-mmcu=$BOARD_MCU", - "-DF_CPU=$BOARD_F_CPU", - "-DUSB_VID=$BOARD_VID", - "-DUSB_PID=$BOARD_PID", - "-DARDUINO=$ARDUINO_VERSION" + "-DF_CPU=$BOARD_F_CPU" ], CCFLAGS=[ "-g", # include debugging info (so errors include line numbers) "-Os", # optimize for size "-Wall", # show warnings - "-fno-exceptions", "-ffunction-sections", # place each function in its own section "-fdata-sections", - "-mmcu=$BOARD_MCU", - "-DF_CPU=$BOARD_F_CPU", "-MMD", # output dependancy info - "-DUSB_VID=$BOARD_VID", - "-DUSB_PID=$BOARD_PID", - "-DARDUINO=$ARDUINO_VERSION" + "-mmcu=$BOARD_MCU", + "-DF_CPU=$BOARD_F_CPU" ], - CFLAGS=["-std=gnu99"], + CXXFLAGS=["-fno-exceptions"], LINKFLAGS=[ "-Os", - "-Wl,--gc-sections" + (",--relax" if BOARD_OPTIONS['build.mcu'] == - "atmega2560" else ""), - "-mmcu=$BOARD_MCU", - "-lm" - ], - - CPPPATH=[ - "$PLATFORMCORE_DIR", - join("$PLATFORM_DIR", "variants", BOARD_OPTIONS['build.variant']) + "-Wl,--gc-sections", + "-mmcu=$BOARD_MCU" ], UPLOADER="avrdude", @@ -82,11 +54,10 @@ env.Replace( "-q", # suppress progress output "-D", # disable auto erase for flash memory "-p", "$BOARD_MCU", - "-C", join("$PLATFORMTOOLS_DIR", "avr", "etc", "avrdude.conf"), - "-c", ("stk500v1" if BOARD_OPTIONS['upload.protocol'] == "stk500" else - BOARD_OPTIONS['upload.protocol']), - "-b", BOARD_OPTIONS['upload.speed'], - "-P", "${UPLOAD_PORT}" + "-C", join("$PLATFORMTOOLS_DIR", "toolchain", "etc", "avrdude.conf"), + "-c", "$UPLOAD_PROTOCOL", + "-b", "$UPLOAD_SPEED", + "-P", "$UPLOAD_PORT" ], UPLOADHEXCMD="$UPLOADER $UPLOADERFLAGS -U flash:w:$SOURCES:i", UPLOADEEPCMD="$UPLOADER $UPLOADERFLAGS -U eeprom:w:$SOURCES:i" @@ -126,22 +97,30 @@ env.Append( env.PrependENVPath( "PATH", - join(env.subst("$PLATFORMTOOLS_DIR"), "avr", "bin") + join(env.subst("$PLATFORMTOOLS_DIR"), "toolchain", "bin") ) +BUILT_LIBS = [] + + # -# Target: Build Core Library +# Process framework script # -target_corelib = env.BuildCoreLibrary() +if "FRAMEWORK" in env: + SConscriptChdir(0) + flibs = SConscript(env.subst(join("$PIOBUILDER_DIR", "scripts", + "frameworks", "${FRAMEWORK}.py")), + exports="env") + BUILT_LIBS += flibs # # Target: Build executable and linkable firmware # -target_elf = env.BuildFirmware([target_corelib]) +target_elf = env.BuildFirmware(BUILT_LIBS + ["m"]) # @@ -181,7 +160,7 @@ AlwaysBuild(upload) # env.Alias("build-eep", [target_eep]) -Default([target_corelib, target_elf, target_hex]) +Default([target_elf, target_hex]) # check for $UPLOAD_PORT variable is_uptarget = ("eep" in COMMAND_LINE_TARGETS or "upload" in diff --git a/platformio/builder/scripts/frameworks/__init__.py b/platformio/builder/scripts/frameworks/__init__.py new file mode 100644 index 00000000..ca6f0304 --- /dev/null +++ b/platformio/builder/scripts/frameworks/__init__.py @@ -0,0 +1,2 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. diff --git a/platformio/builder/scripts/frameworks/arduino.py b/platformio/builder/scripts/frameworks/arduino.py new file mode 100644 index 00000000..6483cfbe --- /dev/null +++ b/platformio/builder/scripts/frameworks/arduino.py @@ -0,0 +1,66 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +""" + Build script for Android Framework (based on Wiring). +""" + +from os.path import join + +from SCons.Script import Import, Return + + +env = None +Import("env") + +BOARD_OPTIONS = env.ParseBoardOptions( + join("$PLATFORMFW_DIR", "boards.txt"), + "${BOARD}" +) +ARDUINO_VERSION = int( + open(join(env.subst("$PLATFORMFW_DIR"), + "version.txt")).read().replace(".", "").strip()) +ARDUINO_FLAGS = [ + "-DARDUINO=%d" % ARDUINO_VERSION, + "-DARDUINO_%s" % BOARD_OPTIONS['build.board'] +] +# usb flags +if "build.usb_product" in BOARD_OPTIONS: + ARDUINO_FLAGS += [ + "-DUSB_VID=%s" % BOARD_OPTIONS['build.vid'], + "-DUSB_PID=%s" % BOARD_OPTIONS['build.pid'], + "-DUSB_PRODUCT=%s" % BOARD_OPTIONS['build.usb_product'].replace( + '"', "") + ] + +env.Append( + ASFLAGS=ARDUINO_FLAGS, + CCFLAGS=ARDUINO_FLAGS, + CPPPATH=[ + join("$BUILD_DIR", "core"), + join("$PLATFORMFW_DIR", "variants", BOARD_OPTIONS['build.variant']) + ] +) + +if "BOARD_MCU" not in env: + env.Replace(BOARD_MCU=BOARD_OPTIONS['build.mcu']) +if "BOARD_F_CPU" not in env: + env.Replace(BOARD_F_CPU=BOARD_OPTIONS['build.f_cpu']) +if "UPLOAD_PROTOCOL" not in env: + env.Replace(UPLOAD_PROTOCOL=BOARD_OPTIONS['upload.protocol']) +if "UPLOAD_SPEED" not in env: + env.Replace(UPLOAD_SPEED=BOARD_OPTIONS['upload.speed']) + + +libs = [] + +# +# Target: Build Core Library +# + +libs.append(env.BuildLibrary( + join("$BUILD_DIR", "core"), + join("$PLATFORMFW_DIR", "cores", BOARD_OPTIONS['build.core']) +)) + +Return("libs") diff --git a/platformio/builder/scripts/frameworks/energia.py b/platformio/builder/scripts/frameworks/energia.py new file mode 100644 index 00000000..9662006f --- /dev/null +++ b/platformio/builder/scripts/frameworks/energia.py @@ -0,0 +1,64 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +""" + Build script for Energia Framework (based on Wiring). +""" + +from os.path import join + +from SCons.Script import Import, Return + + +env = None +Import("env") + +BOARD_OPTIONS = env.ParseBoardOptions( + join("$PLATFORMFW_DIR", "boards.txt"), + "${BOARD}" +) +ENERGIA_VERSION = int( + open(join(env.subst("$PLATFORMFW_DIR"), + "version.txt")).read().replace(".", "").strip()) +ENERGIA_FLAGS = [ + "-DARDUINO=101", + "-DENERGIA=%d" % ENERGIA_VERSION +] + +env.Append( + ASFLAGS=ENERGIA_FLAGS, + CCFLAGS=ENERGIA_FLAGS, + CPPPATH=[ + join("$BUILD_DIR", "core"), + join("$PLATFORMFW_DIR", "variants", BOARD_OPTIONS['build.variant']) + ] +) + +if "BOARD_MCU" not in env: + env.Replace(BOARD_MCU=BOARD_OPTIONS['build.mcu']) +if "BOARD_F_CPU" not in env: + env.Replace(BOARD_F_CPU=BOARD_OPTIONS['build.f_cpu']) +if "UPLOAD_PROTOCOL" not in env and "upload.protocol" in BOARD_OPTIONS: + env.Replace(UPLOAD_PROTOCOL=BOARD_OPTIONS['upload.protocol']) + +# specific linker script for TIVA devices +if "ldscript" in BOARD_OPTIONS: + env.Append( + LINKFLAGS=["-T", join("$PLATFORMFW_DIR", "cores", + BOARD_OPTIONS['build.core'], + BOARD_OPTIONS['ldscript'])] + ) + + +libs = [] + +# +# Target: Build Core Library +# + +libs.append(env.BuildLibrary( + join("$BUILD_DIR", "core"), + join("$PLATFORMFW_DIR", "cores", BOARD_OPTIONS['build.core']) +)) + +Return("libs") diff --git a/platformio/builder/scripts/timsp430.py b/platformio/builder/scripts/timsp430.py index 3cb8160c..25299fa1 100644 --- a/platformio/builder/scripts/timsp430.py +++ b/platformio/builder/scripts/timsp430.py @@ -4,31 +4,17 @@ """ Builder for Texas Instruments MSP430 Ultra-Low Power 16-bit microcontrollers - - Fully compatible with Energia programming language (based on Wiring). """ from os.path import join -from SCons.Script import AlwaysBuild, Builder, Default, DefaultEnvironment +from SCons.Script import (AlwaysBuild, Builder, Default, DefaultEnvironment, + SConscript, SConscriptChdir) -# -# SETUP ENVIRONMENT -# env = DefaultEnvironment() -BOARD_OPTIONS = env.ParseBoardOptions(join("$PLATFORM_DIR", "boards.txt"), - "${BOARD}") env.Replace( - # See https://github.com/energia/Energia/blob/master/app/src/ - # processing/app/Base.java#L45 - ARDUINO_VERSION="101", - ENERGIA_VERSION="12", - - BOARD_MCU=BOARD_OPTIONS['build.mcu'], - BOARD_F_CPU=BOARD_OPTIONS['build.f_cpu'], - AR="msp430-ar", AS="msp430-as", CC="msp430-gcc", @@ -40,11 +26,9 @@ env.Replace( ASFLAGS=[ "-g", # include debugging info (so errors include line numbers) - "-assembler-with-cpp", + "-x", "-assembler-with-cpp", "-mmcu=$BOARD_MCU", - "-DF_CPU=$BOARD_F_CPU", - "-DARDUINO=$ARDUINO_VERSION", - "-DENERGIA=$ENERGIA_VERSION" + "-DF_CPU=$BOARD_F_CPU" ], CCFLAGS=[ "-g", # include debugging info (so errors include line numbers) @@ -52,11 +36,9 @@ env.Replace( "-Wall", # show warnings "-ffunction-sections", # place each function in its own section "-fdata-sections", - "-mmcu=$BOARD_MCU", - "-DF_CPU=$BOARD_F_CPU", "-MMD", # output dependancy info - "-DARDUINO=$ARDUINO_VERSION", - "-DENERGIA=$ENERGIA_VERSION" + "-mmcu=$BOARD_MCU", + "-DF_CPU=$BOARD_F_CPU" ], LINK="$CC", @@ -66,14 +48,9 @@ env.Replace( "-Wl,-gc-sections,-u,main" ], - CPPPATH=[ - "$PLATFORMCORE_DIR", - join("$PLATFORM_DIR", "variants", BOARD_OPTIONS['build.variant']) - ], - - UPLOADER=(join("$PLATFORMTOOLS_DIR", "msp430", "mspdebug", "mspdebug")), + UPLOADER=(join("$PLATFORMTOOLS_DIR", "mspdebug", "mspdebug")), UPLOADERFLAGS=[ - BOARD_OPTIONS['upload.protocol'], + "$UPLOAD_PROTOCOL", "--force-reset" ], UPLOADCMD='$UPLOADER $UPLOADERFLAGS "prog $SOURCES"' @@ -97,22 +74,30 @@ env.Append( env.PrependENVPath( "PATH", - join(env.subst("$PLATFORMTOOLS_DIR"), "msp430", "bin") + join(env.subst("$PLATFORMTOOLS_DIR"), "toolchain", "bin") ) +BUILT_LIBS = [] + + # -# Target: Build Core Library +# Process framework script # -target_corelib = env.BuildCoreLibrary() +if "FRAMEWORK" in env: + SConscriptChdir(0) + flibs = SConscript(env.subst(join("$PIOBUILDER_DIR", "scripts", + "frameworks", "${FRAMEWORK}.py")), + exports="env") + BUILT_LIBS += flibs # # Target: Build executable and linkable firmware # -target_elf = env.BuildFirmware([target_corelib, "m"]) +target_elf = env.BuildFirmware(BUILT_LIBS + ["m"]) # @@ -134,4 +119,4 @@ AlwaysBuild(upload) # Target: Define targets # -Default([target_corelib, target_elf, target_hex]) +Default([target_elf, target_hex]) diff --git a/platformio/builder/scripts/titiva.py b/platformio/builder/scripts/titiva.py index 0e89ea5d..73d9504c 100644 --- a/platformio/builder/scripts/titiva.py +++ b/platformio/builder/scripts/titiva.py @@ -4,29 +4,17 @@ """ Builder for Texas Instruments Tiva C Series ARM Cortex-M4 microcontrollers. - - Fully compatible with Energia programming language (based on Wiring). """ from os.path import join -from SCons.Script import AlwaysBuild, Builder, Default, DefaultEnvironment +from SCons.Script import (AlwaysBuild, Builder, Default, DefaultEnvironment, + SConscript, SConscriptChdir) -# -# SETUP ENVIRONMENT -# env = DefaultEnvironment() -BOARD_OPTIONS = env.ParseBoardOptions(join("$PLATFORM_DIR", "boards.txt"), - "${BOARD}") env.Replace( - ARDUINO_VERSION="101", - ENERGIA_VERSION="12", - - BOARD_MCU=BOARD_OPTIONS['build.mcu'], - BOARD_F_CPU=BOARD_OPTIONS['build.f_cpu'], - AR="arm-none-eabi-ar", AS="arm-none-eabi-as", CC="arm-none-eabi-gcc", @@ -38,16 +26,14 @@ env.Replace( ASFLAGS=[ "-g", # include debugging info (so errors include line numbers) - "-assembler-with-cpp", + "-x", "-assembler-with-cpp", "-Wall", "-mthumb", "-mcpu=cortex-m4", "-mfloat-abi=hard", "-mfpu=fpv4-sp-d16", "-fsingle-precision-constant", - "-DF_CPU=$BOARD_F_CPU", - "-DARDUINO=$ARDUINO_VERSION", - "-DENERGIA=$ENERGIA_VERSION" + "-DF_CPU=$BOARD_F_CPU" ], CCFLAGS=[ @@ -62,10 +48,8 @@ env.Replace( "-mfloat-abi=hard", "-mfpu=fpv4-sp-d16", "-fsingle-precision-constant", - "-DF_CPU=$BOARD_F_CPU", "-MMD", # output dependancy info - "-DARDUINO=$ARDUINO_VERSION", - "-DENERGIA=$ENERGIA_VERSION" + "-DF_CPU=$BOARD_F_CPU" ], CXXFLAGS=[ @@ -78,7 +62,6 @@ env.Replace( "-nostartfiles", "-nostdlib", "-Wl,--gc-sections", - "-T", join("$PLATFORMCORE_DIR", BOARD_OPTIONS['ldscript']), "-Wl,--entry=ResetISR", "-mthumb", "-mcpu=cortex-m4", @@ -87,11 +70,6 @@ env.Replace( "-fsingle-precision-constant" ], - CPPPATH=[ - "$PLATFORMCORE_DIR", - join("$PLATFORM_DIR", "variants", BOARD_OPTIONS['build.variant']) - ], - UPLOADER="lm4flash", UPLOADCMD="$UPLOADER $SOURCES" ) @@ -112,22 +90,30 @@ env.Append( env.PrependENVPath( "PATH", - join(env.subst("$PLATFORMTOOLS_DIR"), "lm4f", "bin") + join(env.subst("$PLATFORMTOOLS_DIR"), "toolchain", "bin") ) +BUILT_LIBS = [] + + # -# Target: Build Core Library +# Process framework script # -target_corelib = env.BuildCoreLibrary() +if "FRAMEWORK" in env: + SConscriptChdir(0) + flibs = SConscript(env.subst(join("$PIOBUILDER_DIR", "scripts", + "frameworks", "${FRAMEWORK}.py")), + exports="env") + BUILT_LIBS += flibs # # Target: Build executable and linkable firmware # -target_elf = env.BuildFirmware([target_corelib, "c", "gcc", "m"]) +target_elf = env.BuildFirmware(BUILT_LIBS + ["c", "gcc", "m"]) # @@ -149,4 +135,4 @@ AlwaysBuild(upload) # Target: Define targets # -Default([target_corelib, target_elf, target_bin]) +Default([target_elf, target_bin]) diff --git a/platformio/builder/tools/platformio.py b/platformio/builder/tools/platformio.py index f76abe65..80c7bd80 100644 --- a/platformio/builder/tools/platformio.py +++ b/platformio/builder/tools/platformio.py @@ -8,23 +8,23 @@ from time import sleep from serial import Serial -def BuildCoreLibrary(env): - corelib = env.Clone() - vdirs = corelib.VariantDirRecursive("$BUILDCORE_DIR", "$PLATFORMCORE_DIR") - return corelib.Library( - corelib.subst("$BUILDCORE_DIR"), - [corelib.GlobCXXFiles(vdir) for vdir in vdirs] +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 BuildFirmware(env, liblist): +def BuildFirmware(env, libslist): src = env.Clone() - vdirs = src.VariantDirRecursive("$BUILDSRC_DIR", + vdirs = src.VariantDirRecursive(join("$BUILD_DIR", "src"), join("$PROJECT_DIR", "src")) return src.Program( join("$BUILD_DIR", "firmware"), [src.GlobCXXFiles(vdir) for vdir in vdirs], - LIBS=liblist, + LIBS=libslist, LIBPATH="$BUILD_DIR", PROGSUFFIX=".elf") @@ -58,14 +58,25 @@ def ParseBoardOptions(env, path, name): env.Exit("Invalid path to boards.txt -> %s" % path) data = {} - _namelen = len(name) + 1 with open(path) as f: for line in f: - if line[0:_namelen] != name + ".": + if not line.strip() or line[0] == "#": continue - line = line[_namelen:].strip() - opt, value = line.split("=", 1) - data[opt] = value + + _group = line[:line.index(".")] + _cpu = name[len(_group):] + line = line[len(_group)+1:].strip() + if _group != name[:len(_group)]: + continue + elif "menu.cpu." in line: + if _cpu not in line: + continue + else: + line = line[len(_cpu)+10:] + + if "=" in line: + opt, value = line.split("=", 1) + data[opt] = value if not data: env.Exit("Unknown Board '%s'" % name) else: @@ -89,7 +100,7 @@ def exists(env): def generate(env): - env.AddMethod(BuildCoreLibrary) + env.AddMethod(BuildLibrary) env.AddMethod(BuildFirmware) env.AddMethod(GlobCXXFiles) env.AddMethod(VariantDirRecursive)