reorganize and remove legacy stuff
authorTimo Savola <tsavola@movial.fi>
Wed, 2 Apr 2008 13:57:44 +0000 (16:57 +0300)
committerTimo Savola <tsavola@movial.fi>
Wed, 2 Apr 2008 14:14:36 +0000 (17:14 +0300)
29 files changed:
.gitignore
bin/matrix [new file with mode: 0755]
bin/matrix-graph [new file with mode: 0755]
boards [deleted file]
components/components [deleted file]
components/components.all [deleted file]
config [deleted file]
documentation/samples/plug [deleted file]
documentation/samples/sample.package [deleted file]
examples/boards [new file with mode: 0644]
examples/config [new file with mode: 0644]
examples/plug [new file with mode: 0644]
examples/rootfs [new file with mode: 0644]
examples/sample.package [new file with mode: 0644]
matrix [deleted file]
matrix-graph [deleted file]
matrix/__init__.py [new file with mode: 0644]
matrix/config.py [new file with mode: 0644]
matrix/git.py [new file with mode: 0644]
matrix/graph.py [new file with mode: 0644]
matrix/matrix.py [new file with mode: 0644]
matrix/rootfs.py [new file with mode: 0644]
mtxbld/__init__.py [deleted file]
mtxbld/config.py [deleted file]
mtxbld/git.py [deleted file]
mtxbld/graph.py [deleted file]
mtxbld/matrix.py [deleted file]
mtxbld/rootfs.py [deleted file]
rootfs [deleted file]

index 6ef0c29..360fa6a 100644 (file)
@@ -2,16 +2,3 @@
 *~
 *.*~
 *.py[co]
-config.local
-scripts/build
-gtk/*
-core/*
-net/*
-af/*
-app/*
-devel/*
-X/*
-.package_map
-.mtxbld-cache
-.matrix-install.lock
-dist
diff --git a/bin/matrix b/bin/matrix
new file mode 100755 (executable)
index 0000000..9067170
--- /dev/null
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+import os.path
+import sys
+
+if os.path.sep in sys.argv[0] and os.path.exists(sys.argv[0]):
+       path = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
+       if os.path.exists(os.path.join(path, 'matrix', '__init__.py')):
+               sys.path.insert(0, path)
+
+from matrix import matrix
+
+try:
+       matrix.main()
+
+except RuntimeError, e:
+       print >>sys.stderr, str(e)
+       sys.exit(1)
+
+except KeyboardInterrupt:
+       sys.exit(1)
diff --git a/bin/matrix-graph b/bin/matrix-graph
new file mode 100755 (executable)
index 0000000..ebdeefd
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+
+import os.path
+import sys
+
+if os.path.sep in sys.argv[0] and os.path.exists(sys.argv[0]):
+       path = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
+       if os.path.exists(os.path.join(path, 'matrix', '__init__.py')):
+               sys.path.insert(0, path)
+
+from matrix import graph
+
+commands = [
+       ("components", graph.ComponentGraph, "Create a components file from the dependancy tree"),
+       ("dot", graph.DotGraph, "Create a graph from the dependancy tree with 'dot'"),
+]
+
+print "\nCopyright (C) 2007-2008 Movial Oy\n"
+
+if len(sys.argv) < 2:
+       print "Please specify one of the following commands:\n"
+       for command, obj, description in commands:
+               print "  %-15s %s" % (command, description)
+       print
+       sys.exit(1)
+
+if sys.argv[1] == "components":
+       g = graph.ComponentGraph(sys.argv[2:])
+elif sys.argv[1] == "dot":
+       g = graph.DotGraph(sys.argv[2:])
+else:
+       print "Unknown command", sys.argv[1]
+       sys.exit(1)
+  
+g.output()
diff --git a/boards b/boards
deleted file mode 100644 (file)
index 9f3b66d..0000000
--- a/boards
+++ /dev/null
@@ -1,39 +0,0 @@
-# The AMD64 64bit x86 cpus on a generic desktop
-Board(name      = 'x86_64',
-      arch      = 'x86_64',
-      gcc_march = 'i686',
-      gnu_host  = 'i686-pc-linux-gnu')
-
-# Generic i686+ desktop PC
-Board(name      = 'x86_i686',
-      arch      = 'i386',
-      gcc_march = 'i686',
-      gnu_host  = 'i686-pc-linux-gnu')
-
-# Plain old i386 PC
-Board(name      = 'x86_i386',
-      arch      = 'i386',
-      gcc_march = 'i386',
-      gnu_host  = 'i386-pc-linux-gnu')
-
-# Generic ARM target for ARMv5 (ARM9/11 processors)
-Board(name        = 'arm',
-      arch        = 'arm',
-      gcc_march   = 'armv5t',
-      gcc_options = '-O2 -mfloat-abi=softfp -Wno-poison-system-directories',
-      gnu_host    = 'arm-unknown-linux-gnueabi')
-
-# Nokia 770 Internet Tablet
-Board(name        = 'nokia_770',
-      arch        = 'arm',
-      gcc_march   = 'armv5t',
-      gcc_options = '-O2 -mfloat-abi=softfp',
-      gnu_host    = 'armv5t-unknown-linux-gnueabi')
-
-# Nokia n800 Internet Tablet
-Board(name        = 'nokia_800',
-      arch        = 'arm',
-      gcc_march   = 'armv6',
-      gcc_mfpu    = 'vfp',
-      gcc_options = '-O2 -mfloat-abi=softfp',
-      gnu_host    = 'armv6-unknown-linux-gnueabi')
diff --git a/components/components b/components/components
deleted file mode 100644 (file)
index e8fe571..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-Component('bsp/base-system',           tag='master')
-Component('bsp/busybox')
-Component('bsp/zlib')
-Component('bsp/udev')
-Component('bsp/openssl')
-Component('bsp/libusb')
-Component('bsp/usbutils')
-Component('bsp/asound2')
-Component('bsp/alsa-utils')
-Component('bsp/ncurses')
-Component('core/common/dbus')
-Component('core/common/glib')
-Component('core/common/dbus-glib')
-Component('core/common/expat')
-Component('core/common/fontconfig')
-Component('core/common/freetype2')
-Component('core/common/drm')
-Component('core/common/tiff')
-Component('core/common/jpeg')
-Component('core/common/libpng')
-Component('core/common/libidl')
-Component('core/common/libxml2')
-Component('core/common/gconf2')
-Component('core/common/hal')
-Component('core/common/hal-info')
-Component('core/common/liboil')
-Component('core/common/bzip2')
-Component('core/common/gnome-mime-data')
-Component('core/common/gnome-vfs')
-Component('core/common/libgpg-error')
-Component('core/common/libgcrypt')
-Component('core/common/gnome-keyring')
-Component('core/common/pixman')
-Component('core/common/tslib')
-Component('core/common/ohm')
-Component('core/X/util/macros')
-Component('core/X/proto/bigreqsproto')
-Component('core/X/proto/compositeproto')
-Component('core/X/proto/damageproto')
-Component('core/X/proto/dmxproto')
-Component('core/X/proto/evieproto')
-Component('core/X/proto/fixesproto')
-Component('core/X/proto/fontcacheproto')
-Component('core/X/proto/fontsproto')
-Component('core/X/proto/glproto')
-Component('core/X/proto/inputproto')
-Component('core/X/proto/kbproto')
-Component('core/X/proto/pmproto')
-Component('core/X/proto/printproto')
-Component('core/X/proto/randrproto')
-Component('core/X/proto/recordproto')
-Component('core/X/proto/renderproto')
-Component('core/X/proto/resourceproto')
-Component('core/X/proto/scrnsaverproto')
-Component('core/X/proto/trapproto')
-Component('core/X/proto/videoproto')
-Component('core/X/proto/x11proto')
-Component('core/X/proto/xcmiscproto')
-Component('core/X/proto/xextproto')
-Component('core/X/proto/xf86bigfontproto')
-Component('core/X/proto/xf86dgaproto')
-Component('core/X/proto/xf86driproto')
-Component('core/X/proto/xf86miscproto')
-Component('core/X/proto/xf86rushproto')
-Component('core/X/proto/xf86vidmodeproto')
-Component('core/X/proto/xorg-protos',  tag='master')
-Component('core/X/lib/libxtrans')
-Component('core/X/lib/libdmx')
-Component('core/X/lib/libfontenc')
-Component('core/X/lib/libFS')
-Component('core/X/lib/libICE')
-Component('core/X/lib/liblbxutil')
-Component('core/X/lib/liboldX')
-Component('core/X/lib/libpciaccess')
-Component('core/X/lib/libSM')
-Component('core/X/lib/libX11')
-Component('core/X/lib/libXau')
-Component('core/X/lib/libXcursor')
-Component('core/X/lib/libXcomposite')
-Component('core/X/lib/libXdamage')
-Component('core/X/lib/libXdmcp')
-Component('core/X/lib/libXevie')
-Component('core/X/lib/libXext')
-Component('core/X/lib/libXfixes')
-Component('core/X/lib/libXfont')
-Component('core/X/lib/libXfontcache')
-Component('core/X/lib/libXft')
-Component('core/X/lib/libXi')
-Component('core/X/lib/libxkbfile')
-Component('core/X/lib/libxkbui')
-Component('core/X/lib/libXmu')
-Component('core/X/lib/libXp')
-Component('core/X/lib/libXpm')
-Component('core/X/lib/libXprintAppUtil')
-Component('core/X/lib/libXprintUtil')
-Component('core/X/lib/libXrandr')
-Component('core/X/lib/libXrender')
-Component('core/X/lib/libXRes')
-Component('core/X/lib/libXScrnSaver')
-Component('core/X/lib/libXt')
-Component('core/X/lib/libXTrap')
-Component('core/X/lib/libXtst')
-Component('core/X/lib/libXv')
-Component('core/X/lib/libXvMC')
-Component('core/X/lib/libXxf86dga')
-Component('core/X/lib/libXxf86misc')
-Component('core/X/lib/libXxf86vm')
-Component('core/X/xserver')
-Component('core/X/driver/xf86-input-evdev')
-Component('core/X/driver/xf86-input-keyboard')
-Component('core/X/driver/xf86-input-tslib')
-Component('core/X/driver/xf86-video-fbdev')
-Component('core/X/app/mkfontdir')
-Component('core/X/app/mkfontscale')
-Component('core/X/app/bdftopcf')
-Component('core/X/app/xkbcomp')
-Component('core/X/app/xkeyboard-config')
-Component('core/X/font/alias')
-Component('core/X/font/util')
-Component('core/fonts/bitstream-vera')
-Component('framework/ui/atk')
-Component('framework/ui/pango')
-Component('framework/ui/cairo')
-Component('framework/ui/gtk+')
-Component('framework/ui/libnotify')
-Component('framework/ui/libsexy')
-Component('framework/ui/libwnck')
-Component('framework/ui/libglade')
-Component('framework/ui/scim')
-Component('framework/ui/hicolor-icon-theme')
-Component('framework/media/gstreamer0.10')
-Component('framework/media/gst-plugins-base')
-Component('framework/media/gst-plugins-good')
-Component('framework/media/gst-plugins-bad')
-Component('framework/media/gst-plugins-ugly')
-Component('framework/media/gst-ffmpeg')
-Component('framework/media/libmad')
-Component('framework/media/libid3tag')
-Component('framework/media/libogg')
-Component('framework/media/tremor')
-Component('framework/device/gnome-volume-manager')
-Component('framework/device/wireless-tools')
-Component('framework/device/libnl')
-Component('framework/device/dhclient')
-Component('framework/device/dhcdbd')
-Component('framework/device/wpa_supplicant')
-Component('framework/device/NetworkManager')
-Component('framework/device/seal')
-Component('framework/browser/xulrunner')
-Component('tools/openssh')
-Component('tools/sigwrap')
-Component('example-ui/matchbox/matchbox-common')
-Component('example-ui/matchbox/matchbox-window-manager')
-Component('example-ui/matchbox/matchbox-desktop')
-Component('example-ui/matchbox/libmatchbox')
-Component('example-ui/matchbox/libfakekey')
-Component('example-ui/matchbox/matchbox-keyboard')
-Component('example-ui/matchbox/matchbox-panel-2')
-Component('example-ui/matchbox/mb-applet-brightness')
-Component('example-ui/matchbox/mb-applet-volume')
-Component('example-ui/themes/sato-theme')
-Component('example-ui/themes/gonxical-theme')
-Component('example-ui/multimedia/kilikali')
-Component('example-ui/system/network-manager-applet')
-Component('example-ui/system/gtk-chtheme')
-Component('example-ui/system/notification-daemon')
-Component('example-ui/branding/brand-movial')
-Component('example-ui/internet/nitehawk')
-Component('example-ui/utilities/rxvt')
-Component('example-ui/utilities/mtpaint')
diff --git a/components/components.all b/components/components.all
deleted file mode 100644 (file)
index 690e6b8..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-Component('bsp/base-system',           tag='master')
-Component('bsp/busybox')
-Component('bsp/zlib')
-Component('bsp/udev')
-Component('bsp/openssl')
-Component('bsp/libusb')
-Component('bsp/usbutils')
-Component('bsp/asound2')
-Component('bsp/alsa-utils')
-Component('bsp/ncurses')
-Component('core/common/libsigc++')
-Component('core/common/dbus')
-Component('core/common/glib')
-Component('core/common/dbus-glib')
-Component('core/common/expat')
-Component('core/common/fontconfig')
-Component('core/common/freetype2')
-Component('core/common/drm')
-Component('core/common/tiff')
-Component('core/common/jpeg')
-Component('core/common/libpng')
-Component('core/common/libidl')
-Component('core/common/libxml2')
-Component('core/common/gconf2')
-Component('core/common/hal')
-Component('core/common/hal-info')
-Component('core/common/liboil')
-Component('core/common/bzip2')
-Component('core/common/gnome-mime-data')
-Component('core/common/gnome-vfs')
-Component('core/common/libgpg-error')
-Component('core/common/libgcrypt')
-Component('core/common/gnome-keyring')
-Component('core/common/pixman')
-Component('core/common/tslib')
-Component('core/common/ohm')
-Component('core/X/util/macros')
-Component('core/X/proto/bigreqsproto')
-Component('core/X/proto/compositeproto')
-Component('core/X/proto/damageproto')
-Component('core/X/proto/dmxproto')
-Component('core/X/proto/evieproto')
-Component('core/X/proto/fixesproto')
-Component('core/X/proto/fontcacheproto')
-Component('core/X/proto/fontsproto')
-Component('core/X/proto/glproto')
-Component('core/X/proto/inputproto')
-Component('core/X/proto/kbproto')
-Component('core/X/proto/pmproto')
-Component('core/X/proto/printproto')
-Component('core/X/proto/randrproto')
-Component('core/X/proto/recordproto')
-Component('core/X/proto/renderproto')
-Component('core/X/proto/resourceproto')
-Component('core/X/proto/scrnsaverproto')
-Component('core/X/proto/trapproto')
-Component('core/X/proto/videoproto')
-Component('core/X/proto/x11proto')
-Component('core/X/proto/xcmiscproto')
-Component('core/X/proto/xextproto')
-Component('core/X/proto/xf86bigfontproto')
-Component('core/X/proto/xf86dgaproto')
-Component('core/X/proto/xf86driproto')
-Component('core/X/proto/xf86miscproto')
-Component('core/X/proto/xf86rushproto')
-Component('core/X/proto/xf86vidmodeproto')
-Component('core/X/proto/xorg-protos',  tag='master')
-Component('core/X/lib/libxtrans')
-Component('core/X/lib/libdmx')
-Component('core/X/lib/libfontenc')
-Component('core/X/lib/libFS')
-Component('core/X/lib/libICE')
-Component('core/X/lib/liblbxutil')
-Component('core/X/lib/liboldX')
-Component('core/X/lib/libpciaccess')
-Component('core/X/lib/libSM')
-Component('core/X/lib/libX11')
-Component('core/X/lib/libXau')
-Component('core/X/lib/libXcursor')
-Component('core/X/lib/libXcomposite')
-Component('core/X/lib/libXdamage')
-Component('core/X/lib/libXdmcp')
-Component('core/X/lib/libXevie')
-Component('core/X/lib/libXext')
-Component('core/X/lib/libXfixes')
-Component('core/X/lib/libXfont')
-Component('core/X/lib/libXfontcache')
-Component('core/X/lib/libXft')
-Component('core/X/lib/libXi')
-Component('core/X/lib/libxkbfile')
-Component('core/X/lib/libxkbui')
-Component('core/X/lib/libXmu')
-Component('core/X/lib/libXp')
-Component('core/X/lib/libXpm')
-Component('core/X/lib/libXprintAppUtil')
-Component('core/X/lib/libXprintUtil')
-Component('core/X/lib/libXrandr')
-Component('core/X/lib/libXrender')
-Component('core/X/lib/libXRes')
-Component('core/X/lib/libXScrnSaver')
-Component('core/X/lib/libXt')
-Component('core/X/lib/libXTrap')
-Component('core/X/lib/libXtst')
-Component('core/X/lib/libXv')
-Component('core/X/lib/libXvMC')
-Component('core/X/lib/libXxf86dga')
-Component('core/X/lib/libXxf86misc')
-Component('core/X/lib/libXxf86vm')
-Component('core/X/xserver')
-Component('core/X/driver/xf86-input-evdev')
-Component('core/X/driver/xf86-input-mouse')
-Component('core/X/driver/xf86-input-keyboard')
-Component('core/X/driver/xf86-input-tslib')
-Component('core/X/driver/xf86-video-fbdev')
-Component('core/X/app/mkfontdir')
-Component('core/X/app/mkfontscale')
-Component('core/X/app/bdftopcf')
-Component('core/X/app/xkbcomp')
-Component('core/X/app/xkeyboard-config')
-Component('core/X/app/xrandr')
-Component('core/X/font/alias')
-Component('core/X/font/util')
-Component('core/X/font/cursor-misc')
-Component('core/X/font/misc-misc')
-Component('core/fonts/bitstream-vera')
-Component('framework/ui/atk')
-Component('framework/ui/pango')
-Component('framework/ui/cairo')
-Component('framework/ui/gtk+')
-Component('framework/ui/libnotify')
-Component('framework/ui/libsexy')
-Component('framework/ui/libwnck')
-Component('framework/ui/libglade')
-Component('framework/ui/scim')
-Component('framework/ui/hicolor-icon-theme')
-Component('framework/media/gstreamer0.10')
-Component('framework/media/gst-plugins-base')
-Component('framework/media/gst-plugins-good')
-Component('framework/media/gst-plugins-bad')
-Component('framework/media/gst-plugins-ugly')
-Component('framework/media/gst-ffmpeg')
-Component('framework/media/libmad')
-Component('framework/media/libid3tag')
-Component('framework/media/libogg')
-Component('framework/media/tremor')
-Component('framework/device/gnome-volume-manager')
-Component('framework/device/wireless-tools')
-Component('framework/device/libnl')
-Component('framework/device/dhclient')
-Component('framework/device/dhcdbd')
-Component('framework/device/wpa_supplicant')
-Component('framework/device/NetworkManager')
-Component('framework/device/seal')
-Component('framework/browser/libgtkembedmoz')
-Component('framework/browser/microb-engine')
-Component('framework/browser/xulrunner')
-Component('framework/addressbook/eds-dbus')
-Component('tools/openssh')
-Component('tools/popt')
-Component('tools/binutils')
-Component('tools/x11perf')
-Component('tools/xnee')
-Component('tools/oprofile')
-Component('tools/python2.5')
-Component('tools/sigwrap')
-Component('example-ui/matchbox/matchbox-common')
-Component('example-ui/matchbox/matchbox-window-manager')
-Component('example-ui/matchbox/matchbox-desktop')
-Component('example-ui/matchbox/libmatchbox')
-Component('example-ui/matchbox/libfakekey')
-Component('example-ui/matchbox/matchbox-keyboard')
-Component('example-ui/matchbox/matchbox-panel-2')
-Component('example-ui/matchbox/mb-applet-brightness')
-Component('example-ui/matchbox/mb-applet-volume')
-Component('example-ui/themes/sato-theme')
-Component('example-ui/themes/gonxical-theme')
-Component('example-ui/multimedia/kilikali')
-Component('example-ui/internet/microb-eal')
-Component('example-ui/internet/browser-eal')
-Component('example-ui/internet/gtkadi')
-Component('example-ui/internet/tablet-browser-ui')
-Component('example-ui/system/network-manager-applet')
-Component('example-ui/system/gtk-chtheme')
-Component('example-ui/system/notification-daemon')
-Component('example-ui/branding/brand-movial')
-Component('example-ui/internet/nitehawk')
-Component('example-ui/utilities/rxvt')
-Component('example-ui/utilities/mtpaint')
diff --git a/config b/config
deleted file mode 100644 (file)
index 22ad0b4..0000000
--- a/config
+++ /dev/null
@@ -1,9 +0,0 @@
-if not roots:
-       roots = ['matrix.movial.fi:/matrix/shared/repo']
-
-if not board:
-       board = 'arm'
-
-# If you are not using a prebuilt rootfs, remove the 'global-cache' flag
-if not flags:
-       flags = ['debug', 'global-cache', 'no-docs', 'no-examples', 'no-tests']
diff --git a/documentation/samples/plug b/documentation/samples/plug
deleted file mode 100644 (file)
index 591cd28..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-# This is a sample .matrix/plug file
-
-MATRIX_BUILD_STYLE = autotools
-
-# this makes the build happen outside of the source tree
-MATRIX_OBJ_DIR = .matrix/obj
-
-# run autogen.sh with no parameters
-MATRIX_AUTOGEN_WITH = ""
-
-ifdef custom_flag
-MATRIX_CONFIGURE_ENV = "CC=my-special-gcc"
-endif
-MATRIX_CONFIGURE_ARGS = "--prefix=/usr"
-
-
diff --git a/documentation/samples/sample.package b/documentation/samples/sample.package
deleted file mode 100644 (file)
index 4dc841f..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-name="sample"
-depends="some_package1:>=1.2.3-m5:flag1,flag2 some_package2"
-conflicts="some_package3::flag some_package1::flag3"
-license="GPL 9"
-description="A Sample Package"
-
-
diff --git a/examples/boards b/examples/boards
new file mode 100644 (file)
index 0000000..9f3b66d
--- /dev/null
@@ -0,0 +1,39 @@
+# The AMD64 64bit x86 cpus on a generic desktop
+Board(name      = 'x86_64',
+      arch      = 'x86_64',
+      gcc_march = 'i686',
+      gnu_host  = 'i686-pc-linux-gnu')
+
+# Generic i686+ desktop PC
+Board(name      = 'x86_i686',
+      arch      = 'i386',
+      gcc_march = 'i686',
+      gnu_host  = 'i686-pc-linux-gnu')
+
+# Plain old i386 PC
+Board(name      = 'x86_i386',
+      arch      = 'i386',
+      gcc_march = 'i386',
+      gnu_host  = 'i386-pc-linux-gnu')
+
+# Generic ARM target for ARMv5 (ARM9/11 processors)
+Board(name        = 'arm',
+      arch        = 'arm',
+      gcc_march   = 'armv5t',
+      gcc_options = '-O2 -mfloat-abi=softfp -Wno-poison-system-directories',
+      gnu_host    = 'arm-unknown-linux-gnueabi')
+
+# Nokia 770 Internet Tablet
+Board(name        = 'nokia_770',
+      arch        = 'arm',
+      gcc_march   = 'armv5t',
+      gcc_options = '-O2 -mfloat-abi=softfp',
+      gnu_host    = 'armv5t-unknown-linux-gnueabi')
+
+# Nokia n800 Internet Tablet
+Board(name        = 'nokia_800',
+      arch        = 'arm',
+      gcc_march   = 'armv6',
+      gcc_mfpu    = 'vfp',
+      gcc_options = '-O2 -mfloat-abi=softfp',
+      gnu_host    = 'armv6-unknown-linux-gnueabi')
diff --git a/examples/config b/examples/config
new file mode 100644 (file)
index 0000000..22ad0b4
--- /dev/null
@@ -0,0 +1,9 @@
+if not roots:
+       roots = ['matrix.movial.fi:/matrix/shared/repo']
+
+if not board:
+       board = 'arm'
+
+# If you are not using a prebuilt rootfs, remove the 'global-cache' flag
+if not flags:
+       flags = ['debug', 'global-cache', 'no-docs', 'no-examples', 'no-tests']
diff --git a/examples/plug b/examples/plug
new file mode 100644 (file)
index 0000000..591cd28
--- /dev/null
@@ -0,0 +1,16 @@
+# This is a sample .matrix/plug file
+
+MATRIX_BUILD_STYLE = autotools
+
+# this makes the build happen outside of the source tree
+MATRIX_OBJ_DIR = .matrix/obj
+
+# run autogen.sh with no parameters
+MATRIX_AUTOGEN_WITH = ""
+
+ifdef custom_flag
+MATRIX_CONFIGURE_ENV = "CC=my-special-gcc"
+endif
+MATRIX_CONFIGURE_ARGS = "--prefix=/usr"
+
+
diff --git a/examples/rootfs b/examples/rootfs
new file mode 100644 (file)
index 0000000..15875f8
--- /dev/null
@@ -0,0 +1,93 @@
+# List of paths that will be copied (recursively)
+include_paths = [
+  "/bin",
+  "/sbin",
+  "/lib",
+  "/etc",
+  "/home",
+  "/usr/bin",
+  "/usr/sbin",
+  "/usr/lib",
+  "/usr/libexec",
+  "/usr/share/locale/en_GB",
+  "/usr/share/X11",
+  "/usr/share/fonts",
+  "/usr/share/hal",
+  "/usr/share/kilikali",
+  "/usr/share/themes",
+  "/usr/share/dbus-1",
+  "/usr/share/application-registry",
+  "/usr/share/applications",
+  "/usr/share/pixmaps",
+  "/usr/share/icons",
+  "/usr/share/scim/icons",
+  "/usr/share/matchbox",
+  "/usr/share/matchbox-keyboard",
+  "/usr/share/matchbox-panel/battery",
+  "/usr/share/gnome",
+  "/usr/share/gnome-volume-manager",
+  "/usr/share/mime-info",
+  "/usr/share/nm-applet",
+  "/usr/share/alsa"
+]
+
+# List of individual files that will be copied
+include_files = [
+  "/usr/share/usb.ids",
+  "/usr/share/terminfo/x/xterm"
+]      
+
+# List of paths that will be filtered out from the copied dirs
+exclude_paths = [
+  "/usr/lib/pkgconfig",
+# The gconv dir in gconv dir is a bug. This is fixed in new SB toolchains.
+  "/usr/lib/gconv/gconv",
+  "/var/run/NetworkManager",
+  "/usr/lib/xulrunner-devel-1.9a9pre"
+]
+
+# List of individual files that will be filtered out from the copy
+exclude_files = [
+       "/usr/share/hal/fdi/preprobe/20thirdparty/10-nfsroot.fdi"
+]
+
+# List of regular expressions that will cause the matched files to be filtered out
+exclude_expressions = [
+  ".*\.l?a$"
+]
+
+# List of paths that will be created as empty directories (with parents if needed)
+created_paths = [
+  "/boot",
+  "/dev/pts",
+  "/lib",
+  "/media",
+  "/mnt",
+  "/proc",
+  "/root",
+  "/sbin",
+  "/home",
+  "/sys",
+  "/tmp",
+  "/var/empty",
+  "/var/run/sshd",
+  "/var/run/NetworkManager",
+  "/var/state/dhcp"
+]
+
+# List of directories to be chowned to (user,group).
+change_owner = {
+  "/home/aeki": ("10042", "10042")
+}
+
+# List of device nodes to be created
+devices = {
+  "console" : ("c", 5, 1),
+  "null"    : ("c", 1, 3),
+  "random"  : ("c", 1, 8),
+  "urandom" : ("c", 1, 9),
+  "tty0"    : ("c", 4, 0),
+  "tty1"    : ("c", 4, 1),
+  "tty2"    : ("c", 4, 2),
+  "tty3"    : ("c", 4, 3)
+}
diff --git a/examples/sample.package b/examples/sample.package
new file mode 100644 (file)
index 0000000..4dc841f
--- /dev/null
@@ -0,0 +1,7 @@
+name="sample"
+depends="some_package1:>=1.2.3-m5:flag1,flag2 some_package2"
+conflicts="some_package3::flag some_package1::flag3"
+license="GPL 9"
+description="A Sample Package"
+
+
diff --git a/matrix b/matrix
deleted file mode 100755 (executable)
index 842e2ca..0000000
--- a/matrix
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-from mtxbld import matrix
-
-try:
-       matrix.main()
-
-except RuntimeError, e:
-       print >>sys.stderr, str(e)
-       sys.exit(1)
-
-except KeyboardInterrupt:
-       sys.exit(1)
diff --git a/matrix-graph b/matrix-graph
deleted file mode 100755 (executable)
index 34a053e..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-from mtxbld import graph
-
-commands = [
-       ("components", graph.ComponentGraph, "Create a components file from the dependancy tree"),
-       ("dot", graph.DotGraph, "Create a graph from the dependancy tree with 'dot'"),
-]
-
-print "\nCopyright (C) 2007-2008 Movial Oy\n"
-
-if len(sys.argv) < 2:
-       print "Please specify one of the following commands:\n"
-       for command, obj, description in commands:
-               print "  %-15s %s" % (command, description)
-       print
-       sys.exit(1)
-
-if sys.argv[1] == "components":
-       g = graph.ComponentGraph(sys.argv[2:])
-elif sys.argv[1] == "dot":
-       g = graph.DotGraph(sys.argv[2:])
-else:
-       print "Unknown command", sys.argv[1]
-       sys.exit(1)
-  
-g.output()
diff --git a/matrix/__init__.py b/matrix/__init__.py
new file mode 100644 (file)
index 0000000..54a18a5
--- /dev/null
@@ -0,0 +1,6 @@
+__all__ = (
+       'config',
+       'git',
+       'matrix',
+       "graph",
+)
diff --git a/matrix/config.py b/matrix/config.py
new file mode 100644 (file)
index 0000000..001594b
--- /dev/null
@@ -0,0 +1,79 @@
+# Copyright (C) 2007-2008 Movial Oy
+# Authors: Timo Savola <tsavola@movial.fi>
+#          Kalle Vahlman <kalle.vahlman@movial.fi>
+
+import os as __os
+
+top_dir = __os.environ.get('MATRIX_TOPDIR', __os.getcwd())
+cache_dir = __os.path.join(top_dir, '.mtxbld-cache')
+global_cache_dir = '/usr/share/matrix/build-cache'
+
+boards = {}
+board = None
+components = {}
+roots = []
+flags = []
+libc = 'glibc'
+verbose = False
+debug = False
+
+class Board:
+       def __init__(self, name, arch, gcc_march, gcc_mcpu='', gcc_mfpu='', gcc_options='', gnu_host='', flash_erase_size='65536', flash_pad_size='0'):
+               self.name = name
+               self.arch = arch
+               self.gcc_march = gcc_march
+               self.gcc_mcpu = gcc_mcpu
+               self.gcc_mfpu = gcc_mfpu
+               self.gcc_options = gcc_options
+               self.gnu_host = gnu_host
+               self.flash_erase_size = flash_erase_size
+               self.flash_pad_size = flash_pad_size
+
+               boards[name] = self
+
+class Component:
+       import git
+
+       from_platform = False
+
+       def __init__(self, name, tag='matrix', tags={}, flags=[]):
+               self.name = name
+
+               self.tags = {}
+               self.tags.update(tags)
+               self.tags[None] = tag
+
+               self.flags = flags
+
+               self.active_url = None
+               self.__active_tag = None
+               self.active_packages = None
+               self.active_depends = None
+               self.__active_hash = None
+               self.active_state = None
+
+               components[name] = self
+
+       def get_active_tag(self):
+               global board
+
+               if self.__active_tag is None:
+                       tag = self.tags.get(board)
+                       if not tag:
+                               tag = self.tags.get(None)
+                       self.__active_tag = tag
+
+               return self.__active_tag
+
+       def get_active_hash(self):
+               if self.__active_hash is None:
+                       self.__active_hash \
+                           = self.git.rev_parse(self.name, 'HEAD')
+
+               return self.__active_hash
+
+class PlatformProvidedComponent(Component):
+       """A Component that is provided by the platform.
+          The sources will not be built during install."""
+
+       from_platform = True
diff --git a/matrix/git.py b/matrix/git.py
new file mode 100644 (file)
index 0000000..ffa5334
--- /dev/null
@@ -0,0 +1,236 @@
+# Copyright (C) 2007-2008 Movial Oy
+# Authors: Timo Savola <tsavola@movial.fi>
+#          Toni Timonen
+
+import os, sys
+import bz2
+
+import config
+
+class Error (RuntimeError):
+       def __init__(self, args, workdir=None):
+               command = ' '.join(args)
+
+               if workdir:
+                       message = 'Failed in %s: %s' % (workdir, command)
+               else:
+                       message = 'Failed: %s' % command
+
+               RuntimeError.__init__(self, message)
+
+def call(args, workdir=None, quiet=False, fail=False):
+       args = ['git'] + args
+
+       if config.debug:
+               if workdir:
+                       print 'Executing in %s:' % workdir,
+               else:
+                       print 'Executing:',
+
+               print ' '.join(args)
+
+       pid = os.fork()
+       if pid == 0:
+               try:
+                       if workdir:
+                               os.chdir(workdir)
+
+                       if quiet:
+                               fd = os.open('/dev/null', os.O_WRONLY)
+                               os.dup2(fd, 1)
+                               os.dup2(fd, 2)
+                               if fd not in (1, 2):
+                                       os.close(fd)
+
+                       os.execvp(args[0], args)
+
+               except Exception, e:
+                       print >>sys.stderr, e
+
+               os._exit(127)
+
+       pid, status = os.waitpid(pid, 0)
+       if status != 0 and fail:
+               raise Error(args, workdir)
+
+       return status
+
+def call_output(args, workdir=None, fd=None, lines=True,wait=True):
+       args = ['git'] + args
+
+       if config.debug:
+               if workdir:
+                       print 'Executing in %s:' % workdir,
+               else:
+                       print 'Executing:',
+
+               print ' '.join(args)
+
+       if fd is None:
+               input, output = os.pipe()
+
+       pid = os.fork()
+       if pid == 0:
+               try:
+                       if workdir:
+                               os.chdir(workdir)
+
+                       if fd is not None:
+                               if fd != 1:
+                                       os.dup2(fd, 1)
+                       else:
+                               os.close(input)
+                               if output != 1:
+                                       os.dup2(output, 1)
+                                       os.close(output)
+
+                       os.execvp(args[0], args)
+
+               except Exception, e:
+                       print >>sys.stderr, e
+
+               os._exit(127)
+
+       if fd is None:
+               os.close(output)
+
+               f = os.fdopen(input, 'r')
+               if lines:
+                       contents = f.readlines()
+               else:
+                       contents = f.read()
+               f.close()
+
+       if not wait and fd is not None:
+               return
+       pid, status = os.waitpid(pid, 0)
+       if status != 0:
+               raise Error(args, workdir)
+
+       if fd is None:
+               if lines:
+                       return [i.strip() for i in contents]
+               else:
+                       return contents
+
+def peek_remote(url, quiet=False):
+       args = ['peek-remote', url]
+       return call(args, quiet=quiet, fail=not quiet) == 0
+
+def clone(name, url, checkout=True):
+       options = []
+       if not checkout:
+               options = ['-n']
+
+       call(['clone'] + options + [url, name], fail=True)
+
+def pull(name, url=None, refspec=None):
+       if url is None and refspec is None:
+               cmd = ['pull']
+       else:
+               cmd = ['pull',url,refspec]
+       if call(cmd, workdir=name) != 0:
+               raise Error('pull', url)
+
+def create_branch(name, branch, point, checkout=False,link=False,force=False):
+       if checkout:
+               command = ['checkout', '-b']
+       else:
+               command = ['branch']
+
+       if not force:
+               call(command + [branch, point], workdir=name, fail=True)
+       else:
+               #If we need more force, branch to temprepo first and rename
+               call(command + ['_matrix_tmp', point], workdir=name, fail=True)
+               call(['branch','-M','_matrix_tmp',branch],workdir=name,fail=True)
+
+       if link:
+               call(['config','branch.%s.merge'%branch,'refs/heads/%s'%branch],workdir=name)
+
+def delete_branch(name, branch, force=False, quiet=False):
+       if force:
+               command = '-D'
+       else:
+               command = '-d'
+
+       return call(['branch', command, branch], name, quiet, not quiet) == 0
+
+def checkout(name, branch):
+       call(['checkout', branch], workdir=name, fail=True)
+
+def rev_parse(name, arg):
+       lines = call_output(['rev-parse', arg], workdir=name)
+       if lines:
+               return lines[0].strip()
+       else:
+               return None
+
+def getvar(name,var):
+       if not os.path.exists(name):
+               return None
+       res=call_output(['config',var],workdir=name)
+       if res and len(res)==1:
+               return res[0]
+       return None
+
+def ls_tree(name, treeish, name_only=False, recursive=False):
+       options = []
+       if name_only:
+               options.append('--name-only')
+       if recursive:
+               options.append('-r')
+
+       return call_output(['ls-tree'] + options + [treeish], workdir=name)
+
+def ls_files(name, options):
+       return call_output(['ls-files'] + options, workdir=name)
+
+
+def archive(name, arch_name,prefix=None,branch='HEAD'):
+       cmd = ['archive','--format=tar']
+       if prefix:
+               cmd.append('--prefix=%s'%prefix)
+
+       inp,out = os.pipe()
+       call_output(cmd+[branch],workdir=name,fd=out,wait=False)
+       os.close(out)
+       infile=os.fdopen(inp)
+       outfile=bz2.BZ2File(arch_name,'w')
+       data=infile.read(1024*50)
+       while data:
+               outfile.write(data)
+               data=infile.read(1024*50)
+       infile.close()
+       outfile.close()
+
+def describe(name,branch='HEAD'):
+       cmd={'args':['describe',branch],'workdir':name}
+       try:
+               call(quiet=True,fail=True,**cmd)
+               res=call_output(**cmd)
+       except Error,e:
+               return None
+
+       if res and len(res)==1:
+               return res[0]
+       return None
+
+def cat_file(name, hash, blob=False, size=False):
+       if blob:
+               option = 'blob'
+       elif size:
+               option = '-s'
+       else:
+               return None
+
+       contents = call_output(['cat-file', option, hash], workdir=name,
+                              lines=False)
+
+       if size:
+               return int(contents.strip())
+       else:
+               return contents
+
+def log(name, options, fd=None):
+       return call_output(['log'] + options + ['--'], workdir=name, fd=fd)
diff --git a/matrix/graph.py b/matrix/graph.py
new file mode 100644 (file)
index 0000000..85ca2a8
--- /dev/null
@@ -0,0 +1,226 @@
+# Copyright (C) 2006-2008 Movial Oy
+# Authors: Kalle Vahlman <kalle.vahlman@movial.fi>
+
+import os
+import sys
+
+import config
+import matrix
+
+
+class Option:
+       short_opt = None
+       long_opt = None
+       takes_arg = False
+       help = None
+       argument = None
+
+       def __init__(self, short_opt, long_opt, takes_arg, help):
+               self.short_opt = short_opt
+               self.long_opt = long_opt
+               self.takes_arg = takes_arg
+               self.help = help
+
+
+class Graph:
+       all_targets = []
+       all_deps = []
+       maxdepth = -1
+
+       options = {}
+       args = []
+       roots = None
+
+       def __init__(self, arguments):
+               self.args.append(Option("h", "help", False,
+                       "Show this help"))
+               self.args.append(Option("c", "components", True,
+                       "Read components from specified file (default: 'components.all')"))
+               self.args.append(Option("i", "input", True,
+                       "Read active components from specified file"))
+               self.args.append(Option("o", "output", True,
+                       "Write graph to specified file (type autodetected)"))
+               self.args.append(Option("r", "root", True,
+                       "Start graphing from specified component"))
+               self.args.append(Option("d", "depth", True,
+                       "Limit graph to specified depth"))
+
+               self.parse_args(arguments)
+
+               try:
+                       if self.options["help"]:
+                               print "\nCopyright (C) 2007 Movial Oy\n"
+                               print "Usage: %s [options]\n" % sys.argv[0]
+
+                               for opt in self.args:
+                                       argstr = ""
+                                       if opt.takes_arg:
+                                               argstr = "[arg]"
+
+                                       print " %-25s %s" % ("-" + opt.short_opt + ", --" + opt.long_opt + " " + argstr, opt.help)
+                       print
+                       sys.exit()
+               except KeyError:
+                       pass
+
+               try:
+                       matrix.parse_config(self.options["components"].argument)
+               except KeyError:
+                       # Default to components.all
+                       matrix.parse_config('components/components.all')
+                       print "huuhaaaaaa"
+
+               matrix.update_components()
+
+               try:
+                       self.maxdepth = int(self.options["depth"].argument)
+               except KeyError:
+                       self.maxdepth = -1
+
+               roots = self.get_roots()
+
+               depth = 1
+               for component in config.components.values():
+                       if roots is None or component.name in roots:
+
+                               self.add_component(component, self.maxdepth, depth)
+
+       def add_component(self, component, maxdepth, depth):
+               for dep in component.active_depends:
+                       dependancy = self.depends(component, dep)
+                       if dependancy not in self.all_deps:
+                               self.all_deps.append(dependancy)
+                       if maxdepth < 0 or depth < maxdepth:
+                               self.add_component(dep, maxdepth, depth + 1)
+
+       def parse_args(self, arguments):
+               arg = None
+               argarg = None
+               for argument in arguments:
+                       if arg is not None and arg.takes_arg:
+                               if not argument.startswith("-"):
+                                       arg.argument = argument
+                                       arg = None
+                                       continue
+                               else:
+                                       arg = None
+
+                       for opt in self.args:
+                               if argument.startswith("-") or argument.startswith("--"):
+                                       if argument[1:] == opt.short_opt or argument[2:] == opt.long_opt:
+                                               self.options[opt.long_opt] = opt
+                                               arg = opt
+                                               break
+
+                       if arg is None:
+                               raise RuntimeError, "Unkown argument '" + argument + "'"
+
+       def read_roots(self, active_components_file="components.active"):
+               f = open(active_components_file, "r")
+               self.roots = []
+               for root in f.readlines():
+                       if len(root.strip()) > 0:
+                               self.roots.append(root.strip())
+               f.close()
+               print "Active components read from", active_components_file
+
+       def get_roots(self):
+               if self.roots is not None:
+                       return self.roots
+
+               try:
+                       active_components_file = self.options["input"].argument
+                       self.read_roots(active_components_file)
+               except KeyError:
+                       try:
+                               self.read_roots()
+                       except IOError:
+                               try:
+                                       self.roots = [self.options["root"].argument]
+                                       print "Active component: %s" % self.roots[0]
+                               except KeyError:
+                                       print "Including all known components as active"
+
+               return self.roots
+
+       def depends(self, component, dependancy):
+               raise NotImplementedError, 'Method depends not implemented by derived class'
+
+       def output(self):
+               raise NotImplementedError, 'Method output not implemented by derived class'
+
+
+class DotGraph(Graph):
+       def __init__(self, arguments):
+               self.args.append(Option("a", "aspect-ratio", True,
+                       "Dot: Aspect ratio for the graph"))
+               self.args.append(Option("s", "size", True,
+                       "Dot: Size of the graph ('xx.x,xx.x', in inches)"))
+               Graph.__init__(self, arguments)
+
+       def depends(self, component, dependancy):
+               return "\t\"" + component.name + "\" -> \"" + dependancy.name + "\""
+
+       def output(self):
+               try:
+                       fname = self.options["output"].argument
+                       otype = self.options["output"].argument[self.options["output"].argument.rindex(".")+1:]
+               except KeyError:
+                       fname = "graph.svg"
+                       otype = "svg"
+
+               try:
+                       ratio = self.options["aspect"].argument
+               except KeyError:
+                       ratio = "0.7" # default to landscape A4
+
+               try:
+                       size = "-Gsize=" + self.options["size"].argument
+               except KeyError:
+                       size = '' # default to native size
+
+               f = open("graph.dot", "w")
+               f.write("digraph {\n")
+               for depstr in self.all_deps:
+                       f.write(depstr + "\n")
+               f.write("}\n")
+               f.close()
+
+               print "Writing", fname
+               os.system("dot graph.dot -Grankdir=LR -Gsplines=true -Nrotate=90 -Gratio=" + ratio + " -T" + otype + " " + size + " -o " + fname)
+               os.remove("graph.dot")
+
+class ComponentGraph(Graph):
+       def __init__(self, arguments):
+               Graph.__init__(self, arguments)
+
+               if self.roots is not None:
+                       for component in config.components.values():
+                               if component.name in self.roots:
+                                       self.all_deps.append(self.depends(None, component))
+                                       break
+
+       def depends(self, component, dependancy):
+               tagstr = ""
+               flagstr = ""
+               if dependancy.tags[None] != "matrix":
+                       tagstr = ",\ttag='" + dependancy.tags[None] + "'"
+               if len(dependancy.flags) > 0:
+                       flagstr = ",\tflags=["
+                       for flag in dependancy.flags:
+                               flagstr += "'" + flag + "',"
+                       flagstr = flagstr[:-1] + "]"
+
+               return "Component('" + dependancy.name + "'" + tagstr + flagstr + ")"
+
+       def output(self):
+               try:
+                       fname = self.options["output"].argument
+               except KeyError:
+                       fname = "components"
+
+               print "Writing", fname
+               f = open(fname, "w")
+               for depstr in self.all_deps:
+                       f.write(depstr + "\n")
+               f.close()
diff --git a/matrix/matrix.py b/matrix/matrix.py
new file mode 100644 (file)
index 0000000..1b0c41e
--- /dev/null
@@ -0,0 +1,591 @@
+# Copyright (C) 2006-2008 Movial Oy
+# Authors: Timo Savola <tsavola@movial.fi>
+#          Toni Timonen
+#          Kalle Vahlman <kalle.vahlman@movial.fi>
+#          Tuomas Kulve <tuomas.kulve@movial.fi>
+
+import sys
+import os
+import glob
+import re
+import tarfile
+from sets import Set as set
+
+import config
+import git
+from rootfs import RootFS
+
+Error = RuntimeError
+
+def main():
+       parse_config('config.local')
+
+       command, params, targets = parse_args(sys.argv)
+
+       parse_config('config')
+       parse_config('boards')
+       parse_config('components/components')
+
+       if 'global-cache' in config.flags:
+               config.cache_dir = config.global_cache_dir
+
+       if not os.path.exists(config.cache_dir):
+               os.makedirs(config.cache_dir)
+
+       all_targets = update_components()
+
+       for name in targets:
+               if name not in config.components:
+                       raise Error('Component "%s" does not exist' % name)
+
+       if not targets:
+               targets = all_targets
+
+       if command == 'install':
+               build_components(targets, **params)
+       elif command == 'download':
+               # Actual downloading took place already in update_components()
+               pass
+       elif command == 'clean':
+               clean_components(targets)
+       elif command == 'pull':
+               pull_components(targets)
+       elif command == 'source-dist':
+               source_dist_components(targets)
+       elif command == 'rootfs':
+               build_rootfs(**params)
+       else:
+               raise Error('Invalid command: ' + command)
+
+def help(file, args):
+       print >>file, '''
+Copyright (C) 2006-2008 Movial Oy
+
+Usage: %(progname)s [options] [command] [params] [component1 component2 ...]
+
+Components must be given like this: core/glibc core/busybox X/xserver
+If no components are given, all of them will be subject to the operation.
+
+Options:
+       -v              Verbose output
+       -d              Debug output
+       -r URL          Specify the root for component git repos to clone from.
+                       If this option is not given, the default specified in
+                       the components file will be used.  This option may be
+                       specified multiple times.
+       -h, --help      Print this help text.
+
+Commands and their parameters:
+
+       download        Only download the components and validate the tree.
+       install         Download, build and install the components.
+               -j N            Execute N build jobs in parallel.
+               -mj N           Run component builds with make -j N.
+       clean           Remove all non-tracked files from the component git
+                       repository directories.
+       pull            Run git pull for the components.
+       source-dist     Download and package the component sources.
+       rootfs          Build a rootfs from the current target installation.
+               -n              Do not clean env.faked and stripped directory.
+               -r              Only generate a stripped rootfs.
+               -j              Only generate a jffs2 image
+               -d              Only generate a rootstrap (development rootfs).
+       list [parameter] [pattern]
+               -p              List packages.
+               -pv             List packages with full details.
+               -c              List components (default).
+               -cdep           List components and their dependencies.
+''' % {'progname': args[0]}
+
+def parse_args(args):
+       def parse_jobs(arg):
+               jobs = int(arg)
+               if jobs <= 0:
+                       raise Error('Please specify a valid number of jobs')
+               return jobs
+
+       command = None
+       params = {}
+       targets = []
+
+       i = 1
+       while i < len(args):
+               if args[i].startswith('-'):
+                       if not command:
+                               if args[i] == '-v':
+                                       config.verbose = True
+                               elif args[i] == '-d':
+                                       config.debug = True
+                               elif args[i] == '-r':
+                                       i += 1
+                                       config.roots.append(args[i])
+                               elif args[i] in ('-h', '--help'):
+                                       help(sys.stdout, args)
+                                       sys.exit(0)
+                               else:
+                                       raise Error('Bad option: ' + args[i])
+                       elif command == 'install':
+                               if args[i] == '-j':
+                                       i += 1
+                                       params['build_jobs'] = parse_jobs(args[i])
+                               elif args[i] == '-mj':
+                                       i += 1
+                                       params['make_jobs'] = parse_jobs(args[i])
+                               else:
+                                       raise Error('Bad parameter: ' + args[i])
+                       elif command == 'rootfs':
+                               if args[i] == '-n':
+                                       i += 1
+                                       params['clean'] = False
+                               elif args[i] == '-r':
+                                       i += 1
+                                       params['rootfs_only'] = True
+                               elif args[i] == '-j':
+                                       i += 1
+                                       params['jffs2_only'] = True
+                               elif args[i] == '-d':
+                                       i += 1
+                                       params['devrootfs_only'] = True
+                       else:
+                               raise Error('Command takes no parameters')
+               elif not command:
+                       command = args[i]
+               else:
+                       targets.append(args[i])
+               i += 1
+
+       if not command:
+               help(sys.stderr, args)
+               sys.exit(1)
+
+       return command, params, targets
+
+def parse_config(path):
+       if os.path.isabs(path):
+               path = os.path.join(config.top_dir, path)
+
+       if os.path.exists(path):
+               print 'Reading', path
+               execfile(path, config.__dict__, config.__dict__)
+
+def update_components():
+       targets = []
+       packages = {}
+
+       for c in config.components.itervalues():
+               update_component_url(c)
+               download_component(c)
+               update_component_packages(c, targets, packages)
+               c.active_depends = []
+
+       update_component_depends(packages)
+
+       return targets
+
+def update_component_url(c):
+       url=git.getvar(c.name,'remote.origin.url')
+       if url:
+               c.active_url=url
+               if config.debug:
+                       print 'Using', c.active_url
+               return
+
+       for root in config.roots:
+               for suffix in ('.git', ''):
+                       url = root + '/' + c.name + suffix
+
+                       if config.debug:
+                               print 'Trying', url
+
+                       if not git.peek_remote(url, quiet=True):
+                               continue
+
+                       c.active_url = url
+                       if config.debug:
+                               print 'Found', c.active_url
+                       return
+
+       raise Error('Failed to locate repository of ' + c.name)
+
+def update_component_depends(packages):
+       for pkg in packages.itervalues():
+               for spec in pkg.depends.split():
+                       depname = Depend(spec).name
+                       deppkg = packages.get(depname)
+
+                       if not deppkg:
+                               print >>sys.stderr, 'Package', pkg.name, \
+                                       'depends on non-existent package', depname
+                               continue
+
+                       if deppkg.component == pkg.component:
+                               continue
+
+                       pkg.component.active_depends.append(deppkg.component)
+
+       fail = False
+       for pkg in packages.itervalues():
+               for spec in pkg.depends.split():
+                       if not Depend(spec).check(packages):
+                               fail = True
+                               print >>sys.stderr, 'Dependency', spec, \
+                                       'failed for', pkg.name
+
+               for spec in pkg.conflicts.split():
+                       if Depend(spec).check(packages):
+                               fail = True
+                               print >>sys.stderr, pkg.name, \
+                                       'conflicts with', spec
+
+       if fail:
+               raise Error('Invalid component tree')
+
+class Depend:
+       regex = re.compile(r'([@]?)([^\s:]+)[:]?([<>=]*)([^\s:]*)[:]?(.*)')
+
+       def __init__(self, spec):
+               match = self.regex.match(spec)
+               if not match:
+                       raise Error('Bad dependency specification: ' + spec)
+
+               self.build, self.name, self.tag_op, self.tag, flags \
+                       = match.groups()
+               self.flags = flags.split()
+
+       def check(self, packages):
+               # TODO: check version and flags
+               return self.name in packages
+
+def execute(args):
+       if config.debug:
+               print 'Executing:', ' '.join(args)
+
+       if os.spawnvp(os.P_WAIT, args[0], args) != 0:
+               raise Error('Failed: ' + ' '.join(args))
+
+def download_component(c, overwrite=False):
+       if os.path.exists(c.name) and not overwrite:
+               return
+
+       print 'Downloading component:', c.name
+
+       execute(['rm', '-rf', c.name])
+       git.clone(c.name, c.active_url, checkout=False)
+
+       branch = c.get_active_tag()
+       git.create_branch(c.name, branch, 'origin/%s'%branch, checkout=True, link=True,force=True)
+
+def update_component_packages(c, targets, packages):
+       c.active_packages = {}
+
+       for path in glob.glob(os.path.join(c.name, '.matrix', '*.package')):
+               name = os.path.basename(path)[:-8]
+
+               pkg = parse_package(name, c, path)
+               if not pkg:
+                       continue
+
+               c.active_packages[name] = pkg
+               packages[name] = pkg
+
+               if config.debug:
+                       print 'Component', c.name, 'provides', name
+
+       if c.active_packages:
+               targets.append(c.name)
+       elif config.debug:
+               print 'Component', c.name, 'does not provide any packages'
+
+class Package:
+       def __init__(self, name, component):
+               self.name = name
+               self.component = component
+
+               self.depends = []
+               self.conflicts = []
+               self.architectures = None
+
+def parse_package(name, component, path):
+       pkg = Package(name, component)
+       execfile(path, pkg.__dict__, pkg.__dict__)
+
+       if pkg.architectures:
+               arch = config.boards[config.board].arch
+               if arch not in pkg.architectures:
+                       return None
+
+       return pkg
+
+def get_active_arch():
+       config.boards[config.board].arch
+
+def build_components(targets, build_jobs=1, make_jobs=1):
+       selected = set([config.components[i] for i in targets])
+
+       depends = None
+       while depends is None or depends:
+               depends = set()
+
+               for c in selected:
+                       for dep in c.active_depends:
+                               if dep not in selected:
+                                       depends.add(dep)
+
+               selected |= depends
+
+       components = list(selected)
+       components.sort()
+
+       if config.debug:
+               print 'Building components:'
+               for c in components:
+                       print '\t' + c.name
+
+       jobs = {}
+
+       while True:
+               found = False
+               for c in components:
+                       if len(jobs) >= build_jobs:
+                               break
+
+                       if component_buildable(c):
+                               found = True
+
+                               if not component_cached(c):
+                                       print 'Starting to build', c.name
+                                       start_job(c, jobs, make_jobs)
+                               else:
+                                       print c.name, 'found from cache'
+                                       c.active_state = 'built'
+
+               if not found and not jobs:
+                       for c in components:
+                               if c.active_state != 'built':
+                                       raise Error('Internal error')
+                       break
+
+               wait_for_job(jobs)
+
+def component_buildable(c):
+       if c.active_state:
+               if config.debug:
+                       print c.name, 'is in state:', c.active_state
+               return False
+
+       for dep in c.active_depends:
+               if config.components[dep.name].active_state != 'built':
+                       if config.debug:
+                               print c.name, 'depends on unbuilt', dep.name
+                       return False
+
+       return True
+
+def component_cached(c):
+       if c.from_platform:
+               return True
+
+       if git.ls_files(c.name, ['-m', '-d']):
+               raise Error('Component contains dirty files: ' + c.name)
+
+       path = os.path.join(config.cache_dir, c.name)
+       if not os.path.exists(path):
+               return False
+
+       file = open(path, 'r')
+       line = file.readline()
+       file.close()
+
+       match = re.match(r'([^\s]+)[\s]?([^\s]*)', line)
+       if not match:
+               return False
+
+       hash, flagstring = match.groups()
+
+       if hash != c.get_active_hash():
+               print 'Component has been changed:', c.name
+               return False
+
+       if flagstring:
+               flags = flagstring.split(',')
+       else:
+               flags = []
+
+       if set(flags) != set(c.flags):
+               print 'Component flags have been changed:', c.name
+               return False
+
+       return True
+
+def update_cache(c):
+       path = os.path.join(config.cache_dir, c.name)
+
+       dir = os.path.dirname(path)
+       if not os.path.exists(dir):
+               os.makedirs(dir)
+
+       file = open(path, 'w')
+       print >>file, c.get_active_hash(), ','.join(c.flags)
+       file.close()
+
+def start_job(c, jobs, make_jobs):
+       board = config.boards[config.board]
+
+       makefile = os.path.join(config.top_dir, 'scripts', 'matrix.mak')
+
+       args = ['make', '--no-print-directory', '-f', makefile, '-C', c.name,
+               '-j', str(make_jobs), 'build_matrix_component',
+               'MATRIX_TOPDIR='    + config.top_dir,
+               'MATRIX_COMPONENT=' + c.name,
+               'MATRIX_ARCH='      + board.arch,
+               'MATRIX_GCC_MARCH=' + board.gcc_march,
+               'MATRIX_GCC_MCPU='  + board.gcc_mcpu,
+               'MATRIX_GCC_MFPU='  + board.gcc_mfpu,
+               'MATRIX_GCC_OPTIONS=' + board.gcc_options,
+               'MATRIX_GNU_HOST='  + board.gnu_host,
+               'MATRIX_LIBC='      + config.libc]
+
+       for flag in config.flags:
+               args.append(flag + '=1')
+
+       if config.verbose:
+               args.append('MATRIX_VERBOSE=1')
+
+       if config.debug:
+               print 'Executing:', ' '.join(args)
+
+       pid = os.spawnvp(os.P_NOWAIT, args[0], args)
+
+       jobs[pid] = c
+       c.active_state = 'running'
+
+def wait_for_job(jobs):
+       if not jobs:
+               return
+
+       pid, status = os.wait()
+
+       c = jobs.get(pid)
+       if not c:
+               return
+
+       del jobs[pid]
+
+       if status == 0:
+               c.active_state = 'built'
+               update_cache(c)
+               print c.name, 'completed'
+       else:
+               c.active_state = 'error'
+               print >>sys.stderr, c.name, 'failed with status:', status
+
+               wait_for_job(jobs)
+               raise Error('Build failed')
+
+def clean_components(targets):
+       if not targets:
+               targets = config.components.keys()
+
+       for name in targets:
+               print 'Cleaning component:', name
+
+               files = git.ls_files(name, ['-o'])
+               paths = [os.path.join(name, i) for i in files]
+               paths.sort()
+               paths.reverse()
+
+               cache = os.path.join(config.cache_dir, name)
+               if os.path.exists(cache):
+                       paths.append(cache)
+
+               for path in paths:
+                       if config.debug:
+                               print 'Deleting', path
+
+                       if os.path.islink(path) or not os.path.isdir(path):
+                               os.remove(path)
+                       else:
+                               os.rmdir(path)
+
+               files = git.ls_files(name, ['-m', '-d'])
+               if files:
+                       print len(files), 'dirty files left in', name
+
+def pull_components(targets):
+       if not targets:
+               targets = config.components.keys()
+
+       for name in targets:
+               print 'Pulling component:', name
+               c = config.components[name]
+               git.pull(name)
+
+def source_dist_components(targets):
+       if not targets:
+               targets = config.components.keys()
+
+       for name in targets:
+               c = config.components[name]
+               generate_component_changes(c, 'dist')
+               package_component_sources(c, 'dist')
+
+def generate_component_changes(c, location):
+       print 'Generating component change log:', c.name
+
+       path = os.path.join(location, c.name) + '.changes'
+
+       pathdir = os.path.dirname(path)
+       if not os.path.exists(pathdir):
+               os.makedirs(pathdir)
+
+       fd = os.open(path, os.O_WRONLY | os.O_CREAT, 0644)
+       git.log(c.name, [c.get_active_tag()], fd=fd)
+       os.close(fd)
+
+def package_component_sources(c, location):
+       print 'Packaging component sources:', c.name
+
+       rev=git.describe(c.name)
+       if rev:
+               rev = '_'+rev
+       else:
+               rev = ''
+       path = os.path.join(location, c.name) + rev + '.tar.bz2'
+       if os.path.exists(path):
+               os.remove(path)
+
+       pathdir = os.path.dirname(path)
+       if not os.path.exists(pathdir):
+               os.makedirs(pathdir)
+
+       git.archive(c.name,path,
+                               prefix=os.path.basename(c.name)+'/',
+                               branch=c.get_active_tag())
+
+def build_rootfs(clean=True, rootfs_only=False, jffs2_only=False, devrootfs_only=False):
+       parse_config('rootfs')
+
+       f = os.popen('sb-conf cu')
+       target = f.read()
+       f.close()
+
+       rootfs = RootFS(target.strip())
+       rootfs.include_paths(config.include_paths)
+       rootfs.include_files(config.include_files)
+       rootfs.filter_paths(config.exclude_paths)
+       rootfs.filter_files(config.exclude_files)
+       rootfs.filter_expressions(config.exclude_expressions)
+       rootfs.add_paths(config.created_paths)
+       rootfs.set_devices(config.devices)
+       rootfs.set_change_owner(config.change_owner)
+       rootfs.set_erase_size(config.boards[config.board].flash_erase_size)
+       rootfs.set_pad_size(config.boards[config.board].flash_pad_size)
+
+       if rootfs_only:
+               rootfs.generate(clean, build_target="rootfs")
+       elif jffs2_only:
+               rootfs.generate(clean, build_target="jffs2")
+       elif devrootfs_only:
+               rootfs.generate(clean, build_target="devrootfs")
+       else:
+               rootfs.generate(clean, build_target="all")
diff --git a/matrix/rootfs.py b/matrix/rootfs.py
new file mode 100644 (file)
index 0000000..593c6ff
--- /dev/null
@@ -0,0 +1,241 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2007-2008 Movial Oy
+# Authors: Kalle Vahlman <kalle.vahlman@movial.fi>
+
+import errno
+import os
+import re
+import shutil
+import sys
+
+class RootFS:
+       builddir = "/tmp"
+       target = None
+
+       # Tools
+       strip = "strip"
+       mknod = "fakeroot -i /tmp/env.faked -s /tmp/env.faked mknod"
+       chmod = "fakeroot -i /tmp/env.faked -s /tmp/env.faked chmod"
+       chown = "fakeroot -i /tmp/env.faked -s /tmp/env.faked chown"
+       mkfs = "fakeroot -i /tmp/env.faked -s /tmp/env.faked mkfs.jffs2"
+       tar = "fakeroot -i /tmp/env.faked -s /tmp/env.faked tar"
+       flash_erase_size = "0x4000"
+       flash_pad_size = "0x3e00000"
+
+       file_list = []
+       remove_list = []
+
+       created_paths = []
+       devices = {}
+       chown_owner = {}
+
+       def __init__(self, mytarget):
+               self.target = mytarget
+
+       def include_paths(self, paths):
+               old_dir = os.getcwd()
+               os.chdir("/targets")
+
+               # Traverse include_paths hierarchies and grab all files there
+               for path in paths:
+                       for root, dirs, files in os.walk(self.target + path):
+                               for f in files:
+                                       self.file_list.append("%s/%s" % (root, f))
+                               if len(files) == 0:
+                                       self.file_list.append(root)
+
+               os.chdir(old_dir)
+
+       def include_files(self, files):
+               old_dir = os.getcwd()
+               os.chdir("/targets")
+
+               # Append included individual files
+               for f in files:
+                       self.file_list.append(self.target + f)
+
+               os.chdir(old_dir)
+
+       def filter_paths(self, paths):
+               # Filter out files in exluded paths
+               for f in self.file_list:
+                       for d in paths:
+                               if f == self.target + d or f.startswith(self.target + d + '/'):
+                                       self.remove_list.append(f)
+
+       def filter_files(self, files):
+               # Filter out exluded files
+               for f in files:
+                       self.remove_list.append(self.target + f)
+
+       def filter_expressions(self, expressions):
+               # Filter out files matching exluded patterns
+               compiled_patterns = []
+               for pattern_str in expressions:
+                       compiled_patterns.append(re.compile(pattern_str))
+
+               for f in self.file_list:
+                       for pattern in compiled_patterns:
+                               if pattern.search(f):
+                                       self.remove_list.append(f)
+
+       def add_paths(self, paths):
+               for path in paths:
+                       self.created_paths.append(path)
+
+       def set_devices(self, devices):
+               self.devices = devices
+
+       def set_change_owner(self, change_owner):
+               self.change_owner= change_owner
+
+       def set_erase_size(self, size):
+               self.flash_erase_size = size
+
+       def set_pad_size(self, size):
+               self.flash_pad_size = size
+
+       def generate(self, clean, build_target="all"):
+               copy_list = self.file_list
+
+               for f in self.remove_list:
+                               try:
+                                       copy_list.remove(f)
+                               except:
+                                       pass
+
+               n_files = len(copy_list)*1.0
+               current_percent = 0.0
+               current_file = 0.0
+
+               old_dir = os.getcwd()
+               os.chdir("/targets")
+
+               if os.path.exists(os.path.join(self.builddir, self.target)):
+                       print "%s exists, please remove it and try again" % os.path.join(self.builddir, self.target)
+                       return
+
+               # Copy the wanted files, strip binaries
+               print "Copying files..."
+               for f in copy_list:
+                       if f[0] == '/':
+                               f = f[1:]
+                       path = os.path.join(self.builddir, os.path.dirname(f))
+                       try:
+                               os.makedirs(path)
+                       except OSError, e:
+                               if e.errno == errno.EEXIST:
+                                       pass
+
+                       if os.path.islink(f):
+                               link_dest = os.readlink(f)
+                               os.symlink(link_dest, os.path.join(self.builddir, f))
+                       elif os.path.isdir(f):
+                               try:
+                                       os.makedirs(os.path.join(self.builddir, f))
+                               except OSError, e:
+                                       if e.errno == errno.EEXIST:
+                                               pass
+                       else:
+                               shutil.copy(f, path)
+                               if not f.endswith(".ko"):
+                                       os.system(self.strip + " " + os.path.join(path,os.path.basename(f)) + " &> /dev/null")
+
+                       if (current_file/n_files)*100 > current_percent:
+                               current_percent += 10.0
+                               print "%0.1f%%" % current_percent,
+                               sys.stdout.flush()
+
+                       current_file += 1.0
+
+               # Create extra directory structure
+               print "\nCreating extra directories..."
+               for d in self.created_paths:
+                       if d[0] == '/':
+                               d = d[1:]
+                       path = os.path.join(self.builddir, self.target, d)
+                       try:
+                               os.makedirs(path)
+                       except OSError, e:
+                               if e.errno == errno.EEXIST:
+                                       pass
+
+               # Remove always the fakeroot environment.
+               if os.path.exists("/tmp/env.faked"):
+                       os.remove("/tmp/env.faked")
+               os.system("touch /tmp/env.faked")
+
+               # Create device nodes
+               print "Creating device nodes..."
+               for d in self.devices.keys():
+                       mode = "664"
+                       if len(self.devices[d]) == 3:
+                               device_type,major,minor = self.devices[d]
+                       else:
+                               device_type,major,minor,mode = self.devices[d]
+                       os.system("%s -m %s %s/%s/dev/%s %s %i %i" % (self.mknod, mode, self.builddir, self.target, d, device_type, major, minor))
+
+               # Fix permissions
+               print "Adjusting ownerships and permissions..."
+               # Make the whole fs root-owned
+               os.system("%s root.root -R %s/%s" % (self.chown, self.builddir, self.target))
+
+               # For sshd:
+               os.system("%s go-r %s/%s/etc/ssh*key*" % (self.chmod, self.builddir, self.target))
+
+               # For /var/empty (sshd requires this):
+               os.system("%s go-rw /%s/%s/var/empty" % (self.chmod, self.builddir, self.target))
+
+               # /dev/null needs to be writable by all:
+               os.system("%s a+rw /%s/%s/dev/null" % (self.chmod, self.builddir, self.target))
+
+               # Set non-root owners
+               print "Setting non-root owner ships..."
+               for d in self.change_owner.keys():
+                       dir = d
+                       if dir[0] == '/':
+                               dir = dir[1:]
+                       if os.path.exists(os.path.join(self.builddir, self.target, dir)):
+                               user,group = self.change_owner[d]
+                               os.system("%s %s.%s -R %s/%s/%s " % (self.chown, user, group, self.builddir, self.target, dir))
+
+               if build_target is "all" or build_target is "rootfs":
+                       print "Creating a rootfs..."
+                       os.system("%s -c --one-file-system -C %s/%s -z -f %s/%s.tgz ." % (self.tar, self.builddir, self.target, self.builddir, self.target))
+               if build_target is "all" or build_target is "jffs2":
+                       print "Creating a root image..."
+                       os.system("%s -p%s -n -e%s -r %s/%s -o %s/%s.jffs2" % (self.mkfs, self.flash_pad_size, self.flash_erase_size, self.builddir, self.target, self.builddir, self.target))
+               if build_target is "all" or build_target is "devrootfs":
+                       print "Creating a rootstrap..."
+                       os.system("%s -c --one-file-system -C /targets/%s -z -f %s/%s-rootstrap.tgz ." % ("tar", self.target, self.builddir, self.target))
+
+               os.chdir(old_dir)
+
+               print "Build finished:"
+               if build_target is "all" or build_target is "rootfs":
+                       s = os.stat(self.builddir + "/" + self.target + ".tgz");
+                       print "\t%s/%s.tgz\t%0.2f MiB" % (self.builddir, self.target, s.st_size/1024.0/1024.0)
+               if build_target is "all" or build_target is "jffs2":
+                       s = os.stat(self.builddir + "/" + self.target + ".jffs2");
+                       print "\t%s/%s.jffs2\t%0.2f MiB" % (self.builddir, self.target, s.st_size/1024.0/1024.0)
+               if build_target is "all" or build_target is "devrootfs":
+                       s = os.stat(self.builddir + "/" + self.target + "-rootstrap.tgz");
+                       print "\t%s/%s-rootstrap.tgz\t%0.2f MiB" % (self.builddir, self.target, s.st_size/1024.0/1024.0)
+
+               if clean:
+                       print "Cleaning up"
+                       os.remove("/tmp/env.faked")
+                       os.system("rm -rf %s/%s" % (self.builddir, self.target))
+
+
+#rootfs = RootFS("ROOTFS")
+#rootfs.include_paths(include_paths)
+#rootfs.include_files(include_files)
+#rootfs.filter_paths(exclude_paths)
+#rootfs.filter_files(exclude_files)
+#rootfs.filter_expressions(exclude_expressions)
+#rootfs.add_paths(created_paths)
+#rootfs.set_devices(devices)
+
+#rootfs.generate()
diff --git a/mtxbld/__init__.py b/mtxbld/__init__.py
deleted file mode 100644 (file)
index 54a18a5..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-__all__ = (
-       'config',
-       'git',
-       'matrix',
-       "graph",
-)
diff --git a/mtxbld/config.py b/mtxbld/config.py
deleted file mode 100644 (file)
index 001594b..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright (C) 2007-2008 Movial Oy
-# Authors: Timo Savola <tsavola@movial.fi>
-#          Kalle Vahlman <kalle.vahlman@movial.fi>
-
-import os as __os
-
-top_dir = __os.environ.get('MATRIX_TOPDIR', __os.getcwd())
-cache_dir = __os.path.join(top_dir, '.mtxbld-cache')
-global_cache_dir = '/usr/share/matrix/build-cache'
-
-boards = {}
-board = None
-components = {}
-roots = []
-flags = []
-libc = 'glibc'
-verbose = False
-debug = False
-
-class Board:
-       def __init__(self, name, arch, gcc_march, gcc_mcpu='', gcc_mfpu='', gcc_options='', gnu_host='', flash_erase_size='65536', flash_pad_size='0'):
-               self.name = name
-               self.arch = arch
-               self.gcc_march = gcc_march
-               self.gcc_mcpu = gcc_mcpu
-               self.gcc_mfpu = gcc_mfpu
-               self.gcc_options = gcc_options
-               self.gnu_host = gnu_host
-               self.flash_erase_size = flash_erase_size
-               self.flash_pad_size = flash_pad_size
-
-               boards[name] = self
-
-class Component:
-       import git
-
-       from_platform = False
-
-       def __init__(self, name, tag='matrix', tags={}, flags=[]):
-               self.name = name
-
-               self.tags = {}
-               self.tags.update(tags)
-               self.tags[None] = tag
-
-               self.flags = flags
-
-               self.active_url = None
-               self.__active_tag = None
-               self.active_packages = None
-               self.active_depends = None
-               self.__active_hash = None
-               self.active_state = None
-
-               components[name] = self
-
-       def get_active_tag(self):
-               global board
-
-               if self.__active_tag is None:
-                       tag = self.tags.get(board)
-                       if not tag:
-                               tag = self.tags.get(None)
-                       self.__active_tag = tag
-
-               return self.__active_tag
-
-       def get_active_hash(self):
-               if self.__active_hash is None:
-                       self.__active_hash \
-                           = self.git.rev_parse(self.name, 'HEAD')
-
-               return self.__active_hash
-
-class PlatformProvidedComponent(Component):
-       """A Component that is provided by the platform.
-          The sources will not be built during install."""
-
-       from_platform = True
diff --git a/mtxbld/git.py b/mtxbld/git.py
deleted file mode 100644 (file)
index ffa5334..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-# Copyright (C) 2007-2008 Movial Oy
-# Authors: Timo Savola <tsavola@movial.fi>
-#          Toni Timonen
-
-import os, sys
-import bz2
-
-import config
-
-class Error (RuntimeError):
-       def __init__(self, args, workdir=None):
-               command = ' '.join(args)
-
-               if workdir:
-                       message = 'Failed in %s: %s' % (workdir, command)
-               else:
-                       message = 'Failed: %s' % command
-
-               RuntimeError.__init__(self, message)
-
-def call(args, workdir=None, quiet=False, fail=False):
-       args = ['git'] + args
-
-       if config.debug:
-               if workdir:
-                       print 'Executing in %s:' % workdir,
-               else:
-                       print 'Executing:',
-
-               print ' '.join(args)
-
-       pid = os.fork()
-       if pid == 0:
-               try:
-                       if workdir:
-                               os.chdir(workdir)
-
-                       if quiet:
-                               fd = os.open('/dev/null', os.O_WRONLY)
-                               os.dup2(fd, 1)
-                               os.dup2(fd, 2)
-                               if fd not in (1, 2):
-                                       os.close(fd)
-
-                       os.execvp(args[0], args)
-
-               except Exception, e:
-                       print >>sys.stderr, e
-
-               os._exit(127)
-
-       pid, status = os.waitpid(pid, 0)
-       if status != 0 and fail:
-               raise Error(args, workdir)
-
-       return status
-
-def call_output(args, workdir=None, fd=None, lines=True,wait=True):
-       args = ['git'] + args
-
-       if config.debug:
-               if workdir:
-                       print 'Executing in %s:' % workdir,
-               else:
-                       print 'Executing:',
-
-               print ' '.join(args)
-
-       if fd is None:
-               input, output = os.pipe()
-
-       pid = os.fork()
-       if pid == 0:
-               try:
-                       if workdir:
-                               os.chdir(workdir)
-
-                       if fd is not None:
-                               if fd != 1:
-                                       os.dup2(fd, 1)
-                       else:
-                               os.close(input)
-                               if output != 1:
-                                       os.dup2(output, 1)
-                                       os.close(output)
-
-                       os.execvp(args[0], args)
-
-               except Exception, e:
-                       print >>sys.stderr, e
-
-               os._exit(127)
-
-       if fd is None:
-               os.close(output)
-
-               f = os.fdopen(input, 'r')
-               if lines:
-                       contents = f.readlines()
-               else:
-                       contents = f.read()
-               f.close()
-
-       if not wait and fd is not None:
-               return
-       pid, status = os.waitpid(pid, 0)
-       if status != 0:
-               raise Error(args, workdir)
-
-       if fd is None:
-               if lines:
-                       return [i.strip() for i in contents]
-               else:
-                       return contents
-
-def peek_remote(url, quiet=False):
-       args = ['peek-remote', url]
-       return call(args, quiet=quiet, fail=not quiet) == 0
-
-def clone(name, url, checkout=True):
-       options = []
-       if not checkout:
-               options = ['-n']
-
-       call(['clone'] + options + [url, name], fail=True)
-
-def pull(name, url=None, refspec=None):
-       if url is None and refspec is None:
-               cmd = ['pull']
-       else:
-               cmd = ['pull',url,refspec]
-       if call(cmd, workdir=name) != 0:
-               raise Error('pull', url)
-
-def create_branch(name, branch, point, checkout=False,link=False,force=False):
-       if checkout:
-               command = ['checkout', '-b']
-       else:
-               command = ['branch']
-
-       if not force:
-               call(command + [branch, point], workdir=name, fail=True)
-       else:
-               #If we need more force, branch to temprepo first and rename
-               call(command + ['_matrix_tmp', point], workdir=name, fail=True)
-               call(['branch','-M','_matrix_tmp',branch],workdir=name,fail=True)
-
-       if link:
-               call(['config','branch.%s.merge'%branch,'refs/heads/%s'%branch],workdir=name)
-
-def delete_branch(name, branch, force=False, quiet=False):
-       if force:
-               command = '-D'
-       else:
-               command = '-d'
-
-       return call(['branch', command, branch], name, quiet, not quiet) == 0
-
-def checkout(name, branch):
-       call(['checkout', branch], workdir=name, fail=True)
-
-def rev_parse(name, arg):
-       lines = call_output(['rev-parse', arg], workdir=name)
-       if lines:
-               return lines[0].strip()
-       else:
-               return None
-
-def getvar(name,var):
-       if not os.path.exists(name):
-               return None
-       res=call_output(['config',var],workdir=name)
-       if res and len(res)==1:
-               return res[0]
-       return None
-
-def ls_tree(name, treeish, name_only=False, recursive=False):
-       options = []
-       if name_only:
-               options.append('--name-only')
-       if recursive:
-               options.append('-r')
-
-       return call_output(['ls-tree'] + options + [treeish], workdir=name)
-
-def ls_files(name, options):
-       return call_output(['ls-files'] + options, workdir=name)
-
-
-def archive(name, arch_name,prefix=None,branch='HEAD'):
-       cmd = ['archive','--format=tar']
-       if prefix:
-               cmd.append('--prefix=%s'%prefix)
-
-       inp,out = os.pipe()
-       call_output(cmd+[branch],workdir=name,fd=out,wait=False)
-       os.close(out)
-       infile=os.fdopen(inp)
-       outfile=bz2.BZ2File(arch_name,'w')
-       data=infile.read(1024*50)
-       while data:
-               outfile.write(data)
-               data=infile.read(1024*50)
-       infile.close()
-       outfile.close()
-
-def describe(name,branch='HEAD'):
-       cmd={'args':['describe',branch],'workdir':name}
-       try:
-               call(quiet=True,fail=True,**cmd)
-               res=call_output(**cmd)
-       except Error,e:
-               return None
-
-       if res and len(res)==1:
-               return res[0]
-       return None
-
-def cat_file(name, hash, blob=False, size=False):
-       if blob:
-               option = 'blob'
-       elif size:
-               option = '-s'
-       else:
-               return None
-
-       contents = call_output(['cat-file', option, hash], workdir=name,
-                              lines=False)
-
-       if size:
-               return int(contents.strip())
-       else:
-               return contents
-
-def log(name, options, fd=None):
-       return call_output(['log'] + options + ['--'], workdir=name, fd=fd)
diff --git a/mtxbld/graph.py b/mtxbld/graph.py
deleted file mode 100644 (file)
index 85ca2a8..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-# Copyright (C) 2006-2008 Movial Oy
-# Authors: Kalle Vahlman <kalle.vahlman@movial.fi>
-
-import os
-import sys
-
-import config
-import matrix
-
-
-class Option:
-       short_opt = None
-       long_opt = None
-       takes_arg = False
-       help = None
-       argument = None
-
-       def __init__(self, short_opt, long_opt, takes_arg, help):
-               self.short_opt = short_opt
-               self.long_opt = long_opt
-               self.takes_arg = takes_arg
-               self.help = help
-
-
-class Graph:
-       all_targets = []
-       all_deps = []
-       maxdepth = -1
-
-       options = {}
-       args = []
-       roots = None
-
-       def __init__(self, arguments):
-               self.args.append(Option("h", "help", False,
-                       "Show this help"))
-               self.args.append(Option("c", "components", True,
-                       "Read components from specified file (default: 'components.all')"))
-               self.args.append(Option("i", "input", True,
-                       "Read active components from specified file"))
-               self.args.append(Option("o", "output", True,
-                       "Write graph to specified file (type autodetected)"))
-               self.args.append(Option("r", "root", True,
-                       "Start graphing from specified component"))
-               self.args.append(Option("d", "depth", True,
-                       "Limit graph to specified depth"))
-
-               self.parse_args(arguments)
-
-               try:
-                       if self.options["help"]:
-                               print "\nCopyright (C) 2007 Movial Oy\n"
-                               print "Usage: %s [options]\n" % sys.argv[0]
-
-                               for opt in self.args:
-                                       argstr = ""
-                                       if opt.takes_arg:
-                                               argstr = "[arg]"
-
-                                       print " %-25s %s" % ("-" + opt.short_opt + ", --" + opt.long_opt + " " + argstr, opt.help)
-                       print
-                       sys.exit()
-               except KeyError:
-                       pass
-
-               try:
-                       matrix.parse_config(self.options["components"].argument)
-               except KeyError:
-                       # Default to components.all
-                       matrix.parse_config('components/components.all')
-                       print "huuhaaaaaa"
-
-               matrix.update_components()
-
-               try:
-                       self.maxdepth = int(self.options["depth"].argument)
-               except KeyError:
-                       self.maxdepth = -1
-
-               roots = self.get_roots()
-
-               depth = 1
-               for component in config.components.values():
-                       if roots is None or component.name in roots:
-
-                               self.add_component(component, self.maxdepth, depth)
-
-       def add_component(self, component, maxdepth, depth):
-               for dep in component.active_depends:
-                       dependancy = self.depends(component, dep)
-                       if dependancy not in self.all_deps:
-                               self.all_deps.append(dependancy)
-                       if maxdepth < 0 or depth < maxdepth:
-                               self.add_component(dep, maxdepth, depth + 1)
-
-       def parse_args(self, arguments):
-               arg = None
-               argarg = None
-               for argument in arguments:
-                       if arg is not None and arg.takes_arg:
-                               if not argument.startswith("-"):
-                                       arg.argument = argument
-                                       arg = None
-                                       continue
-                               else:
-                                       arg = None
-
-                       for opt in self.args:
-                               if argument.startswith("-") or argument.startswith("--"):
-                                       if argument[1:] == opt.short_opt or argument[2:] == opt.long_opt:
-                                               self.options[opt.long_opt] = opt
-                                               arg = opt
-                                               break
-
-                       if arg is None:
-                               raise RuntimeError, "Unkown argument '" + argument + "'"
-
-       def read_roots(self, active_components_file="components.active"):
-               f = open(active_components_file, "r")
-               self.roots = []
-               for root in f.readlines():
-                       if len(root.strip()) > 0:
-                               self.roots.append(root.strip())
-               f.close()
-               print "Active components read from", active_components_file
-
-       def get_roots(self):
-               if self.roots is not None:
-                       return self.roots
-
-               try:
-                       active_components_file = self.options["input"].argument
-                       self.read_roots(active_components_file)
-               except KeyError:
-                       try:
-                               self.read_roots()
-                       except IOError:
-                               try:
-                                       self.roots = [self.options["root"].argument]
-                                       print "Active component: %s" % self.roots[0]
-                               except KeyError:
-                                       print "Including all known components as active"
-
-               return self.roots
-
-       def depends(self, component, dependancy):
-               raise NotImplementedError, 'Method depends not implemented by derived class'
-
-       def output(self):
-               raise NotImplementedError, 'Method output not implemented by derived class'
-
-
-class DotGraph(Graph):
-       def __init__(self, arguments):
-               self.args.append(Option("a", "aspect-ratio", True,
-                       "Dot: Aspect ratio for the graph"))
-               self.args.append(Option("s", "size", True,
-                       "Dot: Size of the graph ('xx.x,xx.x', in inches)"))
-               Graph.__init__(self, arguments)
-
-       def depends(self, component, dependancy):
-               return "\t\"" + component.name + "\" -> \"" + dependancy.name + "\""
-
-       def output(self):
-               try:
-                       fname = self.options["output"].argument
-                       otype = self.options["output"].argument[self.options["output"].argument.rindex(".")+1:]
-               except KeyError:
-                       fname = "graph.svg"
-                       otype = "svg"
-
-               try:
-                       ratio = self.options["aspect"].argument
-               except KeyError:
-                       ratio = "0.7" # default to landscape A4
-
-               try:
-                       size = "-Gsize=" + self.options["size"].argument
-               except KeyError:
-                       size = '' # default to native size
-
-               f = open("graph.dot", "w")
-               f.write("digraph {\n")
-               for depstr in self.all_deps:
-                       f.write(depstr + "\n")
-               f.write("}\n")
-               f.close()
-
-               print "Writing", fname
-               os.system("dot graph.dot -Grankdir=LR -Gsplines=true -Nrotate=90 -Gratio=" + ratio + " -T" + otype + " " + size + " -o " + fname)
-               os.remove("graph.dot")
-
-class ComponentGraph(Graph):
-       def __init__(self, arguments):
-               Graph.__init__(self, arguments)
-
-               if self.roots is not None:
-                       for component in config.components.values():
-                               if component.name in self.roots:
-                                       self.all_deps.append(self.depends(None, component))
-                                       break
-
-       def depends(self, component, dependancy):
-               tagstr = ""
-               flagstr = ""
-               if dependancy.tags[None] != "matrix":
-                       tagstr = ",\ttag='" + dependancy.tags[None] + "'"
-               if len(dependancy.flags) > 0:
-                       flagstr = ",\tflags=["
-                       for flag in dependancy.flags:
-                               flagstr += "'" + flag + "',"
-                       flagstr = flagstr[:-1] + "]"
-
-               return "Component('" + dependancy.name + "'" + tagstr + flagstr + ")"
-
-       def output(self):
-               try:
-                       fname = self.options["output"].argument
-               except KeyError:
-                       fname = "components"
-
-               print "Writing", fname
-               f = open(fname, "w")
-               for depstr in self.all_deps:
-                       f.write(depstr + "\n")
-               f.close()
diff --git a/mtxbld/matrix.py b/mtxbld/matrix.py
deleted file mode 100644 (file)
index 1b0c41e..0000000
+++ /dev/null
@@ -1,591 +0,0 @@
-# Copyright (C) 2006-2008 Movial Oy
-# Authors: Timo Savola <tsavola@movial.fi>
-#          Toni Timonen
-#          Kalle Vahlman <kalle.vahlman@movial.fi>
-#          Tuomas Kulve <tuomas.kulve@movial.fi>
-
-import sys
-import os
-import glob
-import re
-import tarfile
-from sets import Set as set
-
-import config
-import git
-from rootfs import RootFS
-
-Error = RuntimeError
-
-def main():
-       parse_config('config.local')
-
-       command, params, targets = parse_args(sys.argv)
-
-       parse_config('config')
-       parse_config('boards')
-       parse_config('components/components')
-
-       if 'global-cache' in config.flags:
-               config.cache_dir = config.global_cache_dir
-
-       if not os.path.exists(config.cache_dir):
-               os.makedirs(config.cache_dir)
-
-       all_targets = update_components()
-
-       for name in targets:
-               if name not in config.components:
-                       raise Error('Component "%s" does not exist' % name)
-
-       if not targets:
-               targets = all_targets
-
-       if command == 'install':
-               build_components(targets, **params)
-       elif command == 'download':
-               # Actual downloading took place already in update_components()
-               pass
-       elif command == 'clean':
-               clean_components(targets)
-       elif command == 'pull':
-               pull_components(targets)
-       elif command == 'source-dist':
-               source_dist_components(targets)
-       elif command == 'rootfs':
-               build_rootfs(**params)
-       else:
-               raise Error('Invalid command: ' + command)
-
-def help(file, args):
-       print >>file, '''
-Copyright (C) 2006-2008 Movial Oy
-
-Usage: %(progname)s [options] [command] [params] [component1 component2 ...]
-
-Components must be given like this: core/glibc core/busybox X/xserver
-If no components are given, all of them will be subject to the operation.
-
-Options:
-       -v              Verbose output
-       -d              Debug output
-       -r URL          Specify the root for component git repos to clone from.
-                       If this option is not given, the default specified in
-                       the components file will be used.  This option may be
-                       specified multiple times.
-       -h, --help      Print this help text.
-
-Commands and their parameters:
-
-       download        Only download the components and validate the tree.
-       install         Download, build and install the components.
-               -j N            Execute N build jobs in parallel.
-               -mj N           Run component builds with make -j N.
-       clean           Remove all non-tracked files from the component git
-                       repository directories.
-       pull            Run git pull for the components.
-       source-dist     Download and package the component sources.
-       rootfs          Build a rootfs from the current target installation.
-               -n              Do not clean env.faked and stripped directory.
-               -r              Only generate a stripped rootfs.
-               -j              Only generate a jffs2 image
-               -d              Only generate a rootstrap (development rootfs).
-       list [parameter] [pattern]
-               -p              List packages.
-               -pv             List packages with full details.
-               -c              List components (default).
-               -cdep           List components and their dependencies.
-''' % {'progname': args[0]}
-
-def parse_args(args):
-       def parse_jobs(arg):
-               jobs = int(arg)
-               if jobs <= 0:
-                       raise Error('Please specify a valid number of jobs')
-               return jobs
-
-       command = None
-       params = {}
-       targets = []
-
-       i = 1
-       while i < len(args):
-               if args[i].startswith('-'):
-                       if not command:
-                               if args[i] == '-v':
-                                       config.verbose = True
-                               elif args[i] == '-d':
-                                       config.debug = True
-                               elif args[i] == '-r':
-                                       i += 1
-                                       config.roots.append(args[i])
-                               elif args[i] in ('-h', '--help'):
-                                       help(sys.stdout, args)
-                                       sys.exit(0)
-                               else:
-                                       raise Error('Bad option: ' + args[i])
-                       elif command == 'install':
-                               if args[i] == '-j':
-                                       i += 1
-                                       params['build_jobs'] = parse_jobs(args[i])
-                               elif args[i] == '-mj':
-                                       i += 1
-                                       params['make_jobs'] = parse_jobs(args[i])
-                               else:
-                                       raise Error('Bad parameter: ' + args[i])
-                       elif command == 'rootfs':
-                               if args[i] == '-n':
-                                       i += 1
-                                       params['clean'] = False
-                               elif args[i] == '-r':
-                                       i += 1
-                                       params['rootfs_only'] = True
-                               elif args[i] == '-j':
-                                       i += 1
-                                       params['jffs2_only'] = True
-                               elif args[i] == '-d':
-                                       i += 1
-                                       params['devrootfs_only'] = True
-                       else:
-                               raise Error('Command takes no parameters')
-               elif not command:
-                       command = args[i]
-               else:
-                       targets.append(args[i])
-               i += 1
-
-       if not command:
-               help(sys.stderr, args)
-               sys.exit(1)
-
-       return command, params, targets
-
-def parse_config(path):
-       if os.path.isabs(path):
-               path = os.path.join(config.top_dir, path)
-
-       if os.path.exists(path):
-               print 'Reading', path
-               execfile(path, config.__dict__, config.__dict__)
-
-def update_components():
-       targets = []
-       packages = {}
-
-       for c in config.components.itervalues():
-               update_component_url(c)
-               download_component(c)
-               update_component_packages(c, targets, packages)
-               c.active_depends = []
-
-       update_component_depends(packages)
-
-       return targets
-
-def update_component_url(c):
-       url=git.getvar(c.name,'remote.origin.url')
-       if url:
-               c.active_url=url
-               if config.debug:
-                       print 'Using', c.active_url
-               return
-
-       for root in config.roots:
-               for suffix in ('.git', ''):
-                       url = root + '/' + c.name + suffix
-
-                       if config.debug:
-                               print 'Trying', url
-
-                       if not git.peek_remote(url, quiet=True):
-                               continue
-
-                       c.active_url = url
-                       if config.debug:
-                               print 'Found', c.active_url
-                       return
-
-       raise Error('Failed to locate repository of ' + c.name)
-
-def update_component_depends(packages):
-       for pkg in packages.itervalues():
-               for spec in pkg.depends.split():
-                       depname = Depend(spec).name
-                       deppkg = packages.get(depname)
-
-                       if not deppkg:
-                               print >>sys.stderr, 'Package', pkg.name, \
-                                       'depends on non-existent package', depname
-                               continue
-
-                       if deppkg.component == pkg.component:
-                               continue
-
-                       pkg.component.active_depends.append(deppkg.component)
-
-       fail = False
-       for pkg in packages.itervalues():
-               for spec in pkg.depends.split():
-                       if not Depend(spec).check(packages):
-                               fail = True
-                               print >>sys.stderr, 'Dependency', spec, \
-                                       'failed for', pkg.name
-
-               for spec in pkg.conflicts.split():
-                       if Depend(spec).check(packages):
-                               fail = True
-                               print >>sys.stderr, pkg.name, \
-                                       'conflicts with', spec
-
-       if fail:
-               raise Error('Invalid component tree')
-
-class Depend:
-       regex = re.compile(r'([@]?)([^\s:]+)[:]?([<>=]*)([^\s:]*)[:]?(.*)')
-
-       def __init__(self, spec):
-               match = self.regex.match(spec)
-               if not match:
-                       raise Error('Bad dependency specification: ' + spec)
-
-               self.build, self.name, self.tag_op, self.tag, flags \
-                       = match.groups()
-               self.flags = flags.split()
-
-       def check(self, packages):
-               # TODO: check version and flags
-               return self.name in packages
-
-def execute(args):
-       if config.debug:
-               print 'Executing:', ' '.join(args)
-
-       if os.spawnvp(os.P_WAIT, args[0], args) != 0:
-               raise Error('Failed: ' + ' '.join(args))
-
-def download_component(c, overwrite=False):
-       if os.path.exists(c.name) and not overwrite:
-               return
-
-       print 'Downloading component:', c.name
-
-       execute(['rm', '-rf', c.name])
-       git.clone(c.name, c.active_url, checkout=False)
-
-       branch = c.get_active_tag()
-       git.create_branch(c.name, branch, 'origin/%s'%branch, checkout=True, link=True,force=True)
-
-def update_component_packages(c, targets, packages):
-       c.active_packages = {}
-
-       for path in glob.glob(os.path.join(c.name, '.matrix', '*.package')):
-               name = os.path.basename(path)[:-8]
-
-               pkg = parse_package(name, c, path)
-               if not pkg:
-                       continue
-
-               c.active_packages[name] = pkg
-               packages[name] = pkg
-
-               if config.debug:
-                       print 'Component', c.name, 'provides', name
-
-       if c.active_packages:
-               targets.append(c.name)
-       elif config.debug:
-               print 'Component', c.name, 'does not provide any packages'
-
-class Package:
-       def __init__(self, name, component):
-               self.name = name
-               self.component = component
-
-               self.depends = []
-               self.conflicts = []
-               self.architectures = None
-
-def parse_package(name, component, path):
-       pkg = Package(name, component)
-       execfile(path, pkg.__dict__, pkg.__dict__)
-
-       if pkg.architectures:
-               arch = config.boards[config.board].arch
-               if arch not in pkg.architectures:
-                       return None
-
-       return pkg
-
-def get_active_arch():
-       config.boards[config.board].arch
-
-def build_components(targets, build_jobs=1, make_jobs=1):
-       selected = set([config.components[i] for i in targets])
-
-       depends = None
-       while depends is None or depends:
-               depends = set()
-
-               for c in selected:
-                       for dep in c.active_depends:
-                               if dep not in selected:
-                                       depends.add(dep)
-
-               selected |= depends
-
-       components = list(selected)
-       components.sort()
-
-       if config.debug:
-               print 'Building components:'
-               for c in components:
-                       print '\t' + c.name
-
-       jobs = {}
-
-       while True:
-               found = False
-               for c in components:
-                       if len(jobs) >= build_jobs:
-                               break
-
-                       if component_buildable(c):
-                               found = True
-
-                               if not component_cached(c):
-                                       print 'Starting to build', c.name
-                                       start_job(c, jobs, make_jobs)
-                               else:
-                                       print c.name, 'found from cache'
-                                       c.active_state = 'built'
-
-               if not found and not jobs:
-                       for c in components:
-                               if c.active_state != 'built':
-                                       raise Error('Internal error')
-                       break
-
-               wait_for_job(jobs)
-
-def component_buildable(c):
-       if c.active_state:
-               if config.debug:
-                       print c.name, 'is in state:', c.active_state
-               return False
-
-       for dep in c.active_depends:
-               if config.components[dep.name].active_state != 'built':
-                       if config.debug:
-                               print c.name, 'depends on unbuilt', dep.name
-                       return False
-
-       return True
-
-def component_cached(c):
-       if c.from_platform:
-               return True
-
-       if git.ls_files(c.name, ['-m', '-d']):
-               raise Error('Component contains dirty files: ' + c.name)
-
-       path = os.path.join(config.cache_dir, c.name)
-       if not os.path.exists(path):
-               return False
-
-       file = open(path, 'r')
-       line = file.readline()
-       file.close()
-
-       match = re.match(r'([^\s]+)[\s]?([^\s]*)', line)
-       if not match:
-               return False
-
-       hash, flagstring = match.groups()
-
-       if hash != c.get_active_hash():
-               print 'Component has been changed:', c.name
-               return False
-
-       if flagstring:
-               flags = flagstring.split(',')
-       else:
-               flags = []
-
-       if set(flags) != set(c.flags):
-               print 'Component flags have been changed:', c.name
-               return False
-
-       return True
-
-def update_cache(c):
-       path = os.path.join(config.cache_dir, c.name)
-
-       dir = os.path.dirname(path)
-       if not os.path.exists(dir):
-               os.makedirs(dir)
-
-       file = open(path, 'w')
-       print >>file, c.get_active_hash(), ','.join(c.flags)
-       file.close()
-
-def start_job(c, jobs, make_jobs):
-       board = config.boards[config.board]
-
-       makefile = os.path.join(config.top_dir, 'scripts', 'matrix.mak')
-
-       args = ['make', '--no-print-directory', '-f', makefile, '-C', c.name,
-               '-j', str(make_jobs), 'build_matrix_component',
-               'MATRIX_TOPDIR='    + config.top_dir,
-               'MATRIX_COMPONENT=' + c.name,
-               'MATRIX_ARCH='      + board.arch,
-               'MATRIX_GCC_MARCH=' + board.gcc_march,
-               'MATRIX_GCC_MCPU='  + board.gcc_mcpu,
-               'MATRIX_GCC_MFPU='  + board.gcc_mfpu,
-               'MATRIX_GCC_OPTIONS=' + board.gcc_options,
-               'MATRIX_GNU_HOST='  + board.gnu_host,
-               'MATRIX_LIBC='      + config.libc]
-
-       for flag in config.flags:
-               args.append(flag + '=1')
-
-       if config.verbose:
-               args.append('MATRIX_VERBOSE=1')
-
-       if config.debug:
-               print 'Executing:', ' '.join(args)
-
-       pid = os.spawnvp(os.P_NOWAIT, args[0], args)
-
-       jobs[pid] = c
-       c.active_state = 'running'
-
-def wait_for_job(jobs):
-       if not jobs:
-               return
-
-       pid, status = os.wait()
-
-       c = jobs.get(pid)
-       if not c:
-               return
-
-       del jobs[pid]
-
-       if status == 0:
-               c.active_state = 'built'
-               update_cache(c)
-               print c.name, 'completed'
-       else:
-               c.active_state = 'error'
-               print >>sys.stderr, c.name, 'failed with status:', status
-
-               wait_for_job(jobs)
-               raise Error('Build failed')
-
-def clean_components(targets):
-       if not targets:
-               targets = config.components.keys()
-
-       for name in targets:
-               print 'Cleaning component:', name
-
-               files = git.ls_files(name, ['-o'])
-               paths = [os.path.join(name, i) for i in files]
-               paths.sort()
-               paths.reverse()
-
-               cache = os.path.join(config.cache_dir, name)
-               if os.path.exists(cache):
-                       paths.append(cache)
-
-               for path in paths:
-                       if config.debug:
-                               print 'Deleting', path
-
-                       if os.path.islink(path) or not os.path.isdir(path):
-                               os.remove(path)
-                       else:
-                               os.rmdir(path)
-
-               files = git.ls_files(name, ['-m', '-d'])
-               if files:
-                       print len(files), 'dirty files left in', name
-
-def pull_components(targets):
-       if not targets:
-               targets = config.components.keys()
-
-       for name in targets:
-               print 'Pulling component:', name
-               c = config.components[name]
-               git.pull(name)
-
-def source_dist_components(targets):
-       if not targets:
-               targets = config.components.keys()
-
-       for name in targets:
-               c = config.components[name]
-               generate_component_changes(c, 'dist')
-               package_component_sources(c, 'dist')
-
-def generate_component_changes(c, location):
-       print 'Generating component change log:', c.name
-
-       path = os.path.join(location, c.name) + '.changes'
-
-       pathdir = os.path.dirname(path)
-       if not os.path.exists(pathdir):
-               os.makedirs(pathdir)
-
-       fd = os.open(path, os.O_WRONLY | os.O_CREAT, 0644)
-       git.log(c.name, [c.get_active_tag()], fd=fd)
-       os.close(fd)
-
-def package_component_sources(c, location):
-       print 'Packaging component sources:', c.name
-
-       rev=git.describe(c.name)
-       if rev:
-               rev = '_'+rev
-       else:
-               rev = ''
-       path = os.path.join(location, c.name) + rev + '.tar.bz2'
-       if os.path.exists(path):
-               os.remove(path)
-
-       pathdir = os.path.dirname(path)
-       if not os.path.exists(pathdir):
-               os.makedirs(pathdir)
-
-       git.archive(c.name,path,
-                               prefix=os.path.basename(c.name)+'/',
-                               branch=c.get_active_tag())
-
-def build_rootfs(clean=True, rootfs_only=False, jffs2_only=False, devrootfs_only=False):
-       parse_config('rootfs')
-
-       f = os.popen('sb-conf cu')
-       target = f.read()
-       f.close()
-
-       rootfs = RootFS(target.strip())
-       rootfs.include_paths(config.include_paths)
-       rootfs.include_files(config.include_files)
-       rootfs.filter_paths(config.exclude_paths)
-       rootfs.filter_files(config.exclude_files)
-       rootfs.filter_expressions(config.exclude_expressions)
-       rootfs.add_paths(config.created_paths)
-       rootfs.set_devices(config.devices)
-       rootfs.set_change_owner(config.change_owner)
-       rootfs.set_erase_size(config.boards[config.board].flash_erase_size)
-       rootfs.set_pad_size(config.boards[config.board].flash_pad_size)
-
-       if rootfs_only:
-               rootfs.generate(clean, build_target="rootfs")
-       elif jffs2_only:
-               rootfs.generate(clean, build_target="jffs2")
-       elif devrootfs_only:
-               rootfs.generate(clean, build_target="devrootfs")
-       else:
-               rootfs.generate(clean, build_target="all")
diff --git a/mtxbld/rootfs.py b/mtxbld/rootfs.py
deleted file mode 100644 (file)
index 593c6ff..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2007-2008 Movial Oy
-# Authors: Kalle Vahlman <kalle.vahlman@movial.fi>
-
-import errno
-import os
-import re
-import shutil
-import sys
-
-class RootFS:
-       builddir = "/tmp"
-       target = None
-
-       # Tools
-       strip = "strip"
-       mknod = "fakeroot -i /tmp/env.faked -s /tmp/env.faked mknod"
-       chmod = "fakeroot -i /tmp/env.faked -s /tmp/env.faked chmod"
-       chown = "fakeroot -i /tmp/env.faked -s /tmp/env.faked chown"
-       mkfs = "fakeroot -i /tmp/env.faked -s /tmp/env.faked mkfs.jffs2"
-       tar = "fakeroot -i /tmp/env.faked -s /tmp/env.faked tar"
-       flash_erase_size = "0x4000"
-       flash_pad_size = "0x3e00000"
-
-       file_list = []
-       remove_list = []
-
-       created_paths = []
-       devices = {}
-       chown_owner = {}
-
-       def __init__(self, mytarget):
-               self.target = mytarget
-
-       def include_paths(self, paths):
-               old_dir = os.getcwd()
-               os.chdir("/targets")
-
-               # Traverse include_paths hierarchies and grab all files there
-               for path in paths:
-                       for root, dirs, files in os.walk(self.target + path):
-                               for f in files:
-                                       self.file_list.append("%s/%s" % (root, f))
-                               if len(files) == 0:
-                                       self.file_list.append(root)
-
-               os.chdir(old_dir)
-
-       def include_files(self, files):
-               old_dir = os.getcwd()
-               os.chdir("/targets")
-
-               # Append included individual files
-               for f in files:
-                       self.file_list.append(self.target + f)
-
-               os.chdir(old_dir)
-
-       def filter_paths(self, paths):
-               # Filter out files in exluded paths
-               for f in self.file_list:
-                       for d in paths:
-                               if f == self.target + d or f.startswith(self.target + d + '/'):
-                                       self.remove_list.append(f)
-
-       def filter_files(self, files):
-               # Filter out exluded files
-               for f in files:
-                       self.remove_list.append(self.target + f)
-
-       def filter_expressions(self, expressions):
-               # Filter out files matching exluded patterns
-               compiled_patterns = []
-               for pattern_str in expressions:
-                       compiled_patterns.append(re.compile(pattern_str))
-
-               for f in self.file_list:
-                       for pattern in compiled_patterns:
-                               if pattern.search(f):
-                                       self.remove_list.append(f)
-
-       def add_paths(self, paths):
-               for path in paths:
-                       self.created_paths.append(path)
-
-       def set_devices(self, devices):
-               self.devices = devices
-
-       def set_change_owner(self, change_owner):
-               self.change_owner= change_owner
-
-       def set_erase_size(self, size):
-               self.flash_erase_size = size
-
-       def set_pad_size(self, size):
-               self.flash_pad_size = size
-
-       def generate(self, clean, build_target="all"):
-               copy_list = self.file_list
-
-               for f in self.remove_list:
-                               try:
-                                       copy_list.remove(f)
-                               except:
-                                       pass
-
-               n_files = len(copy_list)*1.0
-               current_percent = 0.0
-               current_file = 0.0
-
-               old_dir = os.getcwd()
-               os.chdir("/targets")
-
-               if os.path.exists(os.path.join(self.builddir, self.target)):
-                       print "%s exists, please remove it and try again" % os.path.join(self.builddir, self.target)
-                       return
-
-               # Copy the wanted files, strip binaries
-               print "Copying files..."
-               for f in copy_list:
-                       if f[0] == '/':
-                               f = f[1:]
-                       path = os.path.join(self.builddir, os.path.dirname(f))
-                       try:
-                               os.makedirs(path)
-                       except OSError, e:
-                               if e.errno == errno.EEXIST:
-                                       pass
-
-                       if os.path.islink(f):
-                               link_dest = os.readlink(f)
-                               os.symlink(link_dest, os.path.join(self.builddir, f))
-                       elif os.path.isdir(f):
-                               try:
-                                       os.makedirs(os.path.join(self.builddir, f))
-                               except OSError, e:
-                                       if e.errno == errno.EEXIST:
-                                               pass
-                       else:
-                               shutil.copy(f, path)
-                               if not f.endswith(".ko"):
-                                       os.system(self.strip + " " + os.path.join(path,os.path.basename(f)) + " &> /dev/null")
-
-                       if (current_file/n_files)*100 > current_percent:
-                               current_percent += 10.0
-                               print "%0.1f%%" % current_percent,
-                               sys.stdout.flush()
-
-                       current_file += 1.0
-
-               # Create extra directory structure
-               print "\nCreating extra directories..."
-               for d in self.created_paths:
-                       if d[0] == '/':
-                               d = d[1:]
-                       path = os.path.join(self.builddir, self.target, d)
-                       try:
-                               os.makedirs(path)
-                       except OSError, e:
-                               if e.errno == errno.EEXIST:
-                                       pass
-
-               # Remove always the fakeroot environment.
-               if os.path.exists("/tmp/env.faked"):
-                       os.remove("/tmp/env.faked")
-               os.system("touch /tmp/env.faked")
-
-               # Create device nodes
-               print "Creating device nodes..."
-               for d in self.devices.keys():
-                       mode = "664"
-                       if len(self.devices[d]) == 3:
-                               device_type,major,minor = self.devices[d]
-                       else:
-                               device_type,major,minor,mode = self.devices[d]
-                       os.system("%s -m %s %s/%s/dev/%s %s %i %i" % (self.mknod, mode, self.builddir, self.target, d, device_type, major, minor))
-
-               # Fix permissions
-               print "Adjusting ownerships and permissions..."
-               # Make the whole fs root-owned
-               os.system("%s root.root -R %s/%s" % (self.chown, self.builddir, self.target))
-
-               # For sshd:
-               os.system("%s go-r %s/%s/etc/ssh*key*" % (self.chmod, self.builddir, self.target))
-
-               # For /var/empty (sshd requires this):
-               os.system("%s go-rw /%s/%s/var/empty" % (self.chmod, self.builddir, self.target))
-
-               # /dev/null needs to be writable by all:
-               os.system("%s a+rw /%s/%s/dev/null" % (self.chmod, self.builddir, self.target))
-
-               # Set non-root owners
-               print "Setting non-root owner ships..."
-               for d in self.change_owner.keys():
-                       dir = d
-                       if dir[0] == '/':
-                               dir = dir[1:]
-                       if os.path.exists(os.path.join(self.builddir, self.target, dir)):
-                               user,group = self.change_owner[d]
-                               os.system("%s %s.%s -R %s/%s/%s " % (self.chown, user, group, self.builddir, self.target, dir))
-
-               if build_target is "all" or build_target is "rootfs":
-                       print "Creating a rootfs..."
-                       os.system("%s -c --one-file-system -C %s/%s -z -f %s/%s.tgz ." % (self.tar, self.builddir, self.target, self.builddir, self.target))
-               if build_target is "all" or build_target is "jffs2":
-                       print "Creating a root image..."
-                       os.system("%s -p%s -n -e%s -r %s/%s -o %s/%s.jffs2" % (self.mkfs, self.flash_pad_size, self.flash_erase_size, self.builddir, self.target, self.builddir, self.target))
-               if build_target is "all" or build_target is "devrootfs":
-                       print "Creating a rootstrap..."
-                       os.system("%s -c --one-file-system -C /targets/%s -z -f %s/%s-rootstrap.tgz ." % ("tar", self.target, self.builddir, self.target))
-
-               os.chdir(old_dir)
-
-               print "Build finished:"
-               if build_target is "all" or build_target is "rootfs":
-                       s = os.stat(self.builddir + "/" + self.target + ".tgz");
-                       print "\t%s/%s.tgz\t%0.2f MiB" % (self.builddir, self.target, s.st_size/1024.0/1024.0)
-               if build_target is "all" or build_target is "jffs2":
-                       s = os.stat(self.builddir + "/" + self.target + ".jffs2");
-                       print "\t%s/%s.jffs2\t%0.2f MiB" % (self.builddir, self.target, s.st_size/1024.0/1024.0)
-               if build_target is "all" or build_target is "devrootfs":
-                       s = os.stat(self.builddir + "/" + self.target + "-rootstrap.tgz");
-                       print "\t%s/%s-rootstrap.tgz\t%0.2f MiB" % (self.builddir, self.target, s.st_size/1024.0/1024.0)
-
-               if clean:
-                       print "Cleaning up"
-                       os.remove("/tmp/env.faked")
-                       os.system("rm -rf %s/%s" % (self.builddir, self.target))
-
-
-#rootfs = RootFS("ROOTFS")
-#rootfs.include_paths(include_paths)
-#rootfs.include_files(include_files)
-#rootfs.filter_paths(exclude_paths)
-#rootfs.filter_files(exclude_files)
-#rootfs.filter_expressions(exclude_expressions)
-#rootfs.add_paths(created_paths)
-#rootfs.set_devices(devices)
-
-#rootfs.generate()
diff --git a/rootfs b/rootfs
deleted file mode 100644 (file)
index 15875f8..0000000
--- a/rootfs
+++ /dev/null
@@ -1,93 +0,0 @@
-# List of paths that will be copied (recursively)
-include_paths = [
-  "/bin",
-  "/sbin",
-  "/lib",
-  "/etc",
-  "/home",
-  "/usr/bin",
-  "/usr/sbin",
-  "/usr/lib",
-  "/usr/libexec",
-  "/usr/share/locale/en_GB",
-  "/usr/share/X11",
-  "/usr/share/fonts",
-  "/usr/share/hal",
-  "/usr/share/kilikali",
-  "/usr/share/themes",
-  "/usr/share/dbus-1",
-  "/usr/share/application-registry",
-  "/usr/share/applications",
-  "/usr/share/pixmaps",
-  "/usr/share/icons",
-  "/usr/share/scim/icons",
-  "/usr/share/matchbox",
-  "/usr/share/matchbox-keyboard",
-  "/usr/share/matchbox-panel/battery",
-  "/usr/share/gnome",
-  "/usr/share/gnome-volume-manager",
-  "/usr/share/mime-info",
-  "/usr/share/nm-applet",
-  "/usr/share/alsa"
-]
-
-# List of individual files that will be copied
-include_files = [
-  "/usr/share/usb.ids",
-  "/usr/share/terminfo/x/xterm"
-]      
-
-# List of paths that will be filtered out from the copied dirs
-exclude_paths = [
-  "/usr/lib/pkgconfig",
-# The gconv dir in gconv dir is a bug. This is fixed in new SB toolchains.
-  "/usr/lib/gconv/gconv",
-  "/var/run/NetworkManager",
-  "/usr/lib/xulrunner-devel-1.9a9pre"
-]
-
-# List of individual files that will be filtered out from the copy
-exclude_files = [
-       "/usr/share/hal/fdi/preprobe/20thirdparty/10-nfsroot.fdi"
-]
-
-# List of regular expressions that will cause the matched files to be filtered out
-exclude_expressions = [
-  ".*\.l?a$"
-]
-
-# List of paths that will be created as empty directories (with parents if needed)
-created_paths = [
-  "/boot",
-  "/dev/pts",
-  "/lib",
-  "/media",
-  "/mnt",
-  "/proc",
-  "/root",
-  "/sbin",
-  "/home",
-  "/sys",
-  "/tmp",
-  "/var/empty",
-  "/var/run/sshd",
-  "/var/run/NetworkManager",
-  "/var/state/dhcp"
-]
-
-# List of directories to be chowned to (user,group).
-change_owner = {
-  "/home/aeki": ("10042", "10042")
-}
-
-# List of device nodes to be created
-devices = {
-  "console" : ("c", 5, 1),
-  "null"    : ("c", 1, 3),
-  "random"  : ("c", 1, 8),
-  "urandom" : ("c", 1, 9),
-  "tty0"    : ("c", 4, 0),
-  "tty1"    : ("c", 4, 1),
-  "tty2"    : ("c", 4, 2),
-  "tty3"    : ("c", 4, 3)
-}