Commits

Anonymous committed b868134

#184 mainlined directly

  • Participants
  • Parent commits abf305d

Comments (0)

Files changed (12)

+#
+# This file defines how to build PyMite using Scons (www.scons.org)
+# Usage:
+#   scons tags
+#   scons docs
+#   scons PLATFORM=<platform>
+#
+
+
+import os, string
+
+
+supported_platforms = Glob("src/platform/*")
+allowed_platforms = [os.path.split(x)[1] for x in map(str, supported_platforms)]
+
+
+vars = Variables()
+
+
+# BUILD TARGETS
+if "tags" in COMMAND_LINE_TARGETS or "TAGS" in COMMAND_LINE_TARGETS:
+    vmfiles = Glob("src/vm/*")
+    ctags = Command('tags', vmfiles, "/opt/local/bin/ctags -R *")
+    cscope = Command('cscope.out', vmfiles, "cscope -b -c -R")
+    pyc_tools = Command('src/tools/cscope.out', Glob("src/tools/*.py"),
+                        "src/tools/pycscope.py -f $TARGET $SOURCE")
+    pyc_lib = Command('src/lib/cscope.out', Glob("src/lib/*.py"),
+                      "src/tools/pycscope.py -f $TARGET $SOURCE")
+    tags = Alias('tags', [ctags, cscope, pyc_tools, pyc_lib])
+    Alias('TAGS', tags)
+
+
+# Not yet working
+#elif "check" in COMMAND_LINE_TARGETS or "test" in COMMAND_LINE_TARGETS:
+#    test = SConscript(["src/tests/unit/SConscript", "src/tests/system/SConscript"])
+
+
+elif "docs" in COMMAND_LINE_TARGETS or "html" in COMMAND_LINE_TARGETS:
+    srcpath = os.path.join("docs", "src")
+    rstfiles = Glob(os.path.join(srcpath, "*.txt"))
+    htmlpath = os.path.join("docs", "html")
+    Mkdir(htmlpath)
+    htmlfiles = [string.replace(string.replace(str(s), ".txt", ".html", 1), srcpath, htmlpath, 1)
+                 for s in rstfiles]
+    html = [Command(htmlfiles[i], rstfiles[i], "rst2html.py $SOURCE $TARGET")
+            for i in range(len(rstfiles))]
+    htmlalias = Alias("html", html)
+    Alias("docs", htmlalias)
+
+
+elif "dist" in COMMAND_LINE_TARGETS:
+    assert "PM_RELEASE" in vars.args.keys(), "Must define PM_RELEASE=RR"
+    dist = Command("pymite-%s.tar.gz" % vars.args["PM_RELEASE"], None,
+                   "src/tools/pmDist.py %s" % vars.args["PM_RELEASE"])
+    AlwaysBuild(dist)
+    Alias("dist", dist)
+
+
+# Default: build a platform; desktop by default
+else:
+    if len(vars.args) == 0:
+        vars.args["PLATFORM"] = "desktop"
+    else:
+        if vars.args["PLATFORM"] not in allowed_platforms:
+            print "Error: must define PLATFORM=<plat> where <plat> is from %s" \
+                % str(allowed_platforms)
+            Exit(1)
+    platform_path = "src/platform/%s/SConscript" % vars.args["PLATFORM"]
+    SConscript([platform_path], "vars")

File docs/src/BuildSystem.txt

 :Author:    Dean Hall
 :Id:        $Id$
 
+
 Purpose
 -------
 
 In doing so, it serves both as a design document for the PyMite
 developer and a user manual for the PyMite user.
 
+
 Overview
 --------
 
-PyMite use a makefile-based build system with an allowance for
+PyMite has two build systems available.  The first system is based on Make
+and is the most complete.  The second system is based on Scons_.
+
+.. _Scons: http://www.scons.org
+
+
+The Make Build System
+---------------------
+
+PyMite uses a makefile-based build system with an allowance for
 using features of `GNU make`_.  The project has a ``Makefile`` in the project
 root directory that, when called by typing ``make`` at the command prompt,
 compiles for the desktop platform:
 
     - the PyMite standard library ``src/lib/`` image file,
       ``src/vm/pmstdlib_img.c``, and native code file, ``src/vm/pmstdlib_nat.c``
-    - the PyMite VM archive, ``libpmvm.desktop.a``
+    - the PyMite VM archive, ``libpmvm_desktop.a``
     - the PyMite executable, ``src/platform/desktop/main.out``
 
 More options for building the project are available by using the available
 .. _`GNU make`: http://www.gnu.org/software/make/
 
 
-Requirements
-------------
-
-The PyMite interpreter requires bytecodes created by Python version 2.5 or 2.6.
-
-
 Available Targets
------------------
+~~~~~~~~~~~~~~~~~
 
 GNU projects have, by convention, a set of typical targets that can be built.
 The PyMite build system shall support the following set of targets
 
 
 Build Options
--------------
+~~~~~~~~~~~~~
 
 There are a handful of build options that one can provide to ``make`` that
 alter PyMite's behavior or set its configuration in some way.  The following
     of 4.  The default value is defined in the platform's Makefile.
     Example: ``make HEAP_SIZE=0x1000``
 
-``PLATFORM``:
-    Specifies the intended target platform.  Possible values are the names
-    of the subdirectories in ``src/platform``: ``at91sam7s-ek``,
-    ``avr``, ``mmb103`` and ``desktop``.  The default is ``desktop``.
+``PLATFORM=<platform>``:
+    Builds PyMite for the desired platform.  The given platform must be the
+    name of a subdirectory of ``src/platform/``.  The default is ``desktop``.
     Example: ``make PLATFORM=avr``
 
 
 Self Testing
-------------
+~~~~~~~~~~~~
 
 PyMite has both unit tests and system tests to provide some amount of
 code validity.  Running ``make check`` will build the VM if needed and all self
 way to determine the exit code of the VM.  Perhaps running on a device simulator
 is a better option.
 
+
 Distribution
-------------
+~~~~~~~~~~~~
 
 The PyMite release manager should be the only one who uses the
 distribution target.  The makefiles shall be configured so that
 
 The html documentation shall be pre-built and included in the release file.
 
+
+The Scons Build System
+----------------------
+
+The Scons build system attempts to perform the same operations as the Make
+build system.  However, the Scons build only supports a subset of the targets
+of the Make build.  The reason for including a Scons build system is two-fold:
+First, Scons uses the familiar Python syntax in its build definition files.
+Second, a variety of build systems may help others port PyMite to new platforms.
+
+
+Available Targets
+~~~~~~~~~~~~~~~~~
+
+The Scons build uses the same target names as the Make build.
+However, there are a couple syntactic changes:
+
+=================   ==================================
+Instead of...       Type...
+=================   ==================================
+``make all``        ``scons``
+``make clean``      ``scons <target> -c``
+=================   ==================================
+
+Here are the Scons targets:
+
+``<None>``:
+    Compiles PyMite for the desktop platform.  This is the default target.
+
+``-c``:
+    Deletes the files in this and other directories that are created by
+    building the target.
+
+``TAGS`` or ``tags``:
+    Updates a tags index file for this project.
+    Also updates cscope databases for the VM and pmstdlib source code.
+
+``html`` or ``docs``:
+    Generates the documentation files from ``docs/src/`` and
+    places the output HTML files in ``docs/html/``.
+
+``dist``:
+    Create a distribution tar file for this program.
+    *This target should only be used by the PyMite release manager.*
+
+``PLATFORM=<platform>``:
+    Builds PyMite for the desired platform.  The given platform must be the
+    name of a subdirectory of ``src/platform/``.  The default is ``desktop``.
+    Example: ``make PLATFORM=avr``
+
+
 .. :mode=rest:

File src/platform/at91sam7s-ek/Makefile

 
 # PyMite Configuration
 PLATFORM := $(notdir $(CURDIR))
-PM_LIB_ROOT = pmvm.$(PLATFORM)
+PM_LIB_ROOT = pmvm_$(PLATFORM)
 PM_LIB_FN = lib$(PM_LIB_ROOT).a
 PM_LIB_PATH = ../../vm/$(PM_LIB_FN)
 PM_USR_SOURCES = main.py

File src/platform/at91sam7s-ek/SConscript

+import os
+
+Import("vars")
+
+vars.Add("PM_HEAP_SIZE", "Size of the VM's heap.", 0x3000)
+vars.Add("PM_UART_BAUD", "Baud rate of the ipm serial connection.", 19200)
+vars.Add("IPM", "Add the interactive library to the standard lib", True)
+vars.Add("MCU", "Type of ARM device; the arg to -mmcu.", "arm7tdmi")
+vars.Add("SUBMDL", "The sub-model of ARM device.", "AT91SAM7S64")
+vars.Add("NM", "", "arm-elf-nm")
+vars.Add("OBJCOPY", "", "arm-elf-objcopy")
+vars.Add("OBJDUMP", "", "arm-elf-objdump")
+vars.Add("SIZE", "", "arm-elf-size")
+
+CFLAGS = "-DHEAP_SIZE=$PM_HEAP_SIZE -DUART_BAUD=$PM_UART_BAUD -DROM_RUN" \
+         " -Wall -Wimplicit -Wpointer-arith -Wswitch" \
+         " -Wredundant-decls -Wreturn-type -Wshadow -Wunused" \
+         " -mcpu=$MCU -Os -std=gnu99 -Wall -gstabs -Werror"
+if "DEBUG" in vars.args.keys():
+    CFLAGS = "-g -gstabs -D__DEBUG__=1 " + CFLAGS
+SOURCES = ["main.c", "plat.c"]
+PY_SOURCES = ["main.py"]
+PM_LIB_ROOT = ["pmvm_%s" % vars.args["PLATFORM"]]
+
+envarm = Environment(variables = vars,
+                     CPPPATH = "../../vm",
+                     CC = "arm-elf-gcc",
+                     CCFLAGS = CFLAGS,
+                     CXX = "arm-elf-g++",
+#                     LINKCOM = "arm-elf-ld",
+                     LINKFLAGS = "-nostartfiles -lc -lgcc" \
+                                 " -Tsrc/platform/at91sam7s-ek/$SUBMDL-ROM.ld",
+                     AR = "arm-elf-ar",
+                     ARFLAGS = "rcs",
+                     RANLIB = "arm-elf-ranlib")
+envarm.AppendENVPath("PATH", "/opt/local/bin")
+aobj1 = envarm.Object("Cstartup_SAM7.o", "Cstartup_SAM7.c")
+aobj2 = envarm.Object("Cstartup.o", "Cstartup.S")
+
+env = envarm.Clone(CCFLAGS = "-mthumb " + CFLAGS)
+vmlib = SConscript(["../../vm/SConscript"], ["env", "vars"])
+img_sources = Command(["main_img.c", "main_nat.c"], [PY_SOURCES],
+    "src/tools/pmImgCreator.py -c -u -o src/platform/at91sam7s-ek/main_img.c" \
+    " --native-file=src/platform/at91sam7s-ek/main_nat.c $SOURCES")
+elf = env.Program("main.elf", SOURCES + img_sources + aobj1 + aobj2,
+                  LIBS = PM_LIB_ROOT, LIBPATH = ["../../vm"])
+
+hex = env.Command("main.hex", "main.elf", "$OBJCOPY -O ihex $SOURCE $TARGET")
+bin = env.Command("main.bin", "main.elf", "$OBJCOPY -O binary $SOURCE $TARGET")
+#lss = env.Command("main.lss", "main.elf", "$OBJDUMP -h -S -C $SOURCE > $TARGET")
+#sym = env.Command("main.sym", "main.elf", "$NM -n $SOURCE > $TARGET")

File src/platform/avr/Makefile

 
 # PyMite Configuration
 PLATFORM := $(notdir $(CURDIR))
-PM_LIB_ROOT = pmvm.$(PLATFORM)
+PM_LIB_ROOT = pmvm_$(PLATFORM)
 PM_LIB_FN = lib$(PM_LIB_ROOT).a
 PM_LIB_PATH = ../../vm/$(PM_LIB_FN)
 PM_USR_SOURCES = main.py ../../lib/avr.py

File src/platform/avr/SConscript

+import os
+
+Import("vars")
+
+vars.Add("PM_HEAP_SIZE", "Size of the VM's heap.", 0x0D00)
+vars.Add("PM_UART_BAUD", "Baud rate of the ipm serial connection.", "19200UL")
+vars.Add("IPM", "Add the interactive library to the standard lib", True)
+vars.Add("MCU", "Type of AVR device; the arg to -mmcu.", "atmega103")
+vars.Add("F_CPU", "Operating frequency of the AVR device.", "4000000UL")
+vars.Add("NM", "", "avr-nm")
+vars.Add("OBJCOPY", "", "avr-objcopy")
+vars.Add("OBJDUMP", "", "avr-objdump")
+vars.Add("SIZE", "", "avr-size")
+
+CFLAGS = "-DHEAP_SIZE=$PM_HEAP_SIZE -DF_CPU=$F_CPU -DUART_BAUD=$PM_UART_BAUD" \
+         " -Wall -Wstrict-prototypes -Wimplicit -Werror" \
+         " -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums" \
+         " -mmcu=$MCU -Os -std=gnu99"
+if "DEBUG" in vars.args.keys():
+    CFLAGS = "-g -gstabs -D__DEBUG__=1 " + CFLAGS
+SOURCES = ["main.c", "plat.c"]
+PY_SOURCES = ["main.py"]
+PM_LIB_ROOT = ["pmvm_%s" % vars.args["PLATFORM"]]
+
+env = Environment(variables = vars,
+                  CPPPATH = "../../vm",
+                  CC = "avr-gcc",
+                  CCFLAGS = CFLAGS,
+                  CXX = "avr-g++",
+                  LINKFLAGS = "-mmcu=$MCU",
+                  AR = "avr-ar",
+                  ARFLAGS = "rcs",
+                  RANLIB = "avr-ranlib")
+env.AppendENVPath("PATH", "/usr/local/AVRMacPack/bin")
+
+vmlib = SConscript(["../../vm/SConscript"], ["env", "vars"])
+img_sources = env.Command(["main_img.c", "main_nat.c"], [PY_SOURCES],
+    "src/tools/pmImgCreator.py -c -u -o src/platform/avr/main_img.c" \
+    " --native-file=src/platform/avr/main_nat.c $SOURCES")
+elf = env.Program("main.elf", SOURCES + img_sources,
+                  LIBS = PM_LIB_ROOT, LIBPATH = ["../../vm"])
+
+hex = env.Command("main.hex", "main.elf",
+                  "$OBJCOPY -O ihex -R .eeprom $SOURCE $TARGET")
+#eep = env.Command("main.eep", "main.elf", '-$OBJCOPY -j .eeprom' \
+#                  ' --set-section-flags=.eeprom="alloc,load"' \
+#                  ' --change-section-lma .eeprom=0 -O ihex $SOURCE $TARGET')
+#lss = env.Command("main.lss", "main.elf", "$OBJDUMP -h -S $SOURCE > $TARGET")
+#sym = env.Command("main.sym", "main.elf", "$NM -n $SOURCE > $TARGET")

File src/platform/desktop/Makefile

 # PyMite Configuration
 PLATFORM := $(notdir $(CURDIR))
-PM_LIB_ROOT = pmvm.$(PLATFORM)
+PM_LIB_ROOT = pmvm_$(PLATFORM)
 PM_LIB_FN = lib$(PM_LIB_ROOT).a
 PM_LIB_PATH = ../../vm/$(PM_LIB_FN)
 PM_USR_SOURCES = main.py

File src/platform/desktop/SConscript

+Import("vars")
+
+vars.Add("HEAP_SIZE", "Size of the VM's heap.", 0x2000)
+vars.Add("IPM", "Add the interactive library to the standard lib", True)
+
+CFLAGS = "-DHEAP_SIZE=$HEAP_SIZE " \
+         "-Os -Wall -gstabs -Wstrict-prototypes -Werror"
+if "DEBUG" in vars.args.keys():
+    CFLAGS = "-g -ggdb -D__DEBUG__=1 " + CFLAGS
+SOURCES = ["main.c", "plat.c"]
+PY_SOURCES = ["main.py"]
+PM_LIB_ROOT = ["pmvm_%s" % vars.args["PLATFORM"]]
+
+env = Environment(variables = vars,
+                  CPPPATH = "../../vm",
+                  CCFLAGS = CFLAGS)
+
+vmlib = SConscript(["../../vm/SConscript"], ["env", "vars"])
+img_sources = Command(["main_img.c", "main_nat.c"], [PY_SOURCES],
+    "src/tools/pmImgCreator.py -c -u -o src/platform/desktop/main_img.c" \
+    " --native-file=src/platform/desktop/main_nat.c $SOURCES")
+main = env.Program("main.out", SOURCES + img_sources,
+                   LIBS = PM_LIB_ROOT, LIBPATH = ["../../vm"])

File src/platform/mmb103/Makefile

 
 # PyMite Configuration
 PLATFORM := $(notdir $(CURDIR))
-PM_LIB_ROOT = pmvm.$(PLATFORM)
+PM_LIB_ROOT = pmvm_$(PLATFORM)
 PM_LIB_FN = lib$(PM_LIB_ROOT).a
 PM_LIB_PATH = ../../vm/$(PM_LIB_FN)
 PM_USR_SOURCES = main.py mmb.py

File src/platform/mmb103/SConscript

+import os
+
+Import("vars")
+
+vars.Add("PM_HEAP_SIZE", "Size of the VM's heap.", 0x0D00)
+vars.Add("PM_UART_BAUD", "Baud rate of the ipm serial connection.", "19200UL")
+vars.Add("IPM", "Add the interactive library to the standard lib", True)
+vars.Add("MCU", "Type of AVR device; the arg to -mmcu.", "atmega103")
+vars.Add("F_CPU", "Operating frequency of the AVR device.", "4000000UL")
+vars.Add("NM", "", "avr-nm")
+vars.Add("OBJCOPY", "", "avr-objcopy")
+vars.Add("OBJDUMP", "", "avr-objdump")
+vars.Add("SIZE", "", "avr-size")
+
+CFLAGS = "-DHEAP_SIZE=$PM_HEAP_SIZE -DF_CPU=$F_CPU -DUART_BAUD=$PM_UART_BAUD" \
+         " -Wall -Wstrict-prototypes -Wimplicit -Werror" \
+         " -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums" \
+         " -mmcu=$MCU -Os -std=gnu99"
+if "DEBUG" in vars.args.keys():
+    CFLAGS = "-g -gstabs -D__DEBUG__=1 " + CFLAGS
+SOURCES = ["main.c", "plat.c"]
+PY_SOURCES = ["main.py", "mmb.py"]
+PM_LIB_ROOT = ["pmvm_%s" % vars.args["PLATFORM"]]
+
+env = Environment(variables = vars,
+                  CPPPATH = "../../vm",
+                  CC = "avr-gcc",
+                  CCFLAGS = CFLAGS,
+                  CXX = "avr-g++",
+                  LINKFLAGS = "-mmcu=$MCU",
+                  AR = "avr-ar",
+                  ARFLAGS = "rcs",
+                  RANLIB = "avr-ranlib")
+env.AppendENVPath("PATH", "/usr/local/AVRMacPack/bin")
+
+vmlib = SConscript(["../../vm/SConscript"], ["env", "vars"])
+img_sources = env.Command(["main_img.c", "main_nat.c"], [PY_SOURCES],
+    "src/tools/pmImgCreator.py -c -u -o src/platform/mmb103/main_img.c" \
+    " --native-file=src/platform/mmb103/main_nat.c $SOURCES")
+elf = env.Program("main.elf", SOURCES + img_sources,
+                  LIBS = ["mmb103", PM_LIB_ROOT], LIBPATH = [".", "../../vm"])
+
+hex = env.Command("main.hex", "main.elf",
+                  "$OBJCOPY -O ihex -R .eeprom $SOURCE $TARGET")
+#eep = env.Command("main.eep", "main.elf", '-$OBJCOPY -j .eeprom' \
+#                  ' --set-section-flags=.eeprom="alloc,load"' \
+#                  ' --change-section-lma .eeprom=0 -O ihex $SOURCE $TARGET')
+#lss = env.Command("main.lss", "main.elf", "$OBJDUMP -h -S $SOURCE > $TARGET")
+#sym = env.Command("main.sym", "main.elf", "$NM -n $SOURCE > $TARGET")

File src/tests/system/SConscript

+#
+# NOTICE: This does not work yet.
+#
+
+
+import os
+
+vars = Variables()
+vars.args["PLATFORM"] = "check"
+vars.Add("PM_HEAP_SIZE", "Size of the VM's heap.", 0x2000)
+vars.Add("IPM", "Add the interactive library to the standard lib", True)
+
+CFLAGS = "-g -ggdb -D__DEBUG__=1 -DHEAP_SIZE=$PM_HEAP_SIZE " \
+         "-Os -Wall -gstabs -Wstrict-prototypes -Werror"
+#PY_SOURCES = ["main.py"]
+PM_LIB_ROOT = ["pmvm_%s" % vars.args["PLATFORM"]]
+
+env = Environment(variables = vars,
+                  CPPPATH = "../../vm",
+                  CCFLAGS = CFLAGS)
+
+vmlib = SConscript(["../../vm/SConscript"], ["env", "vars"])
+
+plat = env.Object("plat.c")
+check = []
+for fn in Glob("t*.c"):
+    fn = str(fn)
+    fnroot = os.path.splitext(fn)[0]
+    img_sources = Command([fnroot+"_img.c", fnroot+"_nat.c"], [fnroot+".py"],
+        "src/tools/pmImgCreator.py -c -u -o src/tests/system/%s_img.c" \
+        " --native-file=src/tests/system/%s_nat.c $SOURCES" % (fnroot, fnroot))
+    check.append(env.Program(fnroot+".out",
+                             [fn, plat] + img_sources,
+                             LIBS = PM_LIB_ROOT, LIBPATH = ["../../vm"]))
+    
+    # Execute the test
+    exe= Builder(action="./$SOURCE")
+    env.Append(BUILDERS = {'Exe' : exe})
+    env.Exe(fnroot+".exe", fnroot+".out")
+
+Alias("check", check)

File src/vm/SConscript

+Import("env", "vars")
+
+SOURCES = Glob("*.c")
+PMSTDLIB_SOURCES = ["../lib/list.py",
+                    "../lib/dict.py",
+                    "../lib/__bi.py",
+                    "../lib/sys.py",
+                    "../lib/string.py",]
+if env["IPM"] == True:
+    PMSTDLIB_SOURCES.append("../lib/ipm.py")
+
+
+img_sources = Command(["pmstdlib_img.c", "pmstdlib_nat.c"], [PMSTDLIB_SOURCES],
+    "src/tools/pmImgCreator.py -c -s -o src/vm/pmstdlib_img.c" \
+    " --native-file=src/vm/pmstdlib_nat.c $SOURCES")
+lib = env.Library("pmvm_%s" % vars.args["PLATFORM"],
+                  SOURCES + img_sources, ARFLAGS = "rcs")
+env.Precious(lib)
+
+
+Return("lib")