]> rtime.felk.cvut.cz Git - frescor/frsh-forb.git/commitdiff
Add 'src/forb/' from commit '1ef7503676513a85e80eda0950d0cae8b60d7cdd'
authorMichal Sojka <sojkam1@fel.cvut.cz>
Thu, 27 Jan 2011 13:43:12 +0000 (14:43 +0100)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Thu, 27 Jan 2011 13:43:12 +0000 (14:43 +0100)
git-subtree-dir: src/forb
git-subtree-mainline: 0ab53f8d451359d07df47e14f6cd84e93010392b
git-subtree-split: 1ef7503676513a85e80eda0950d0cae8b60d7cdd

158 files changed:
.gitmodules [new file with mode: 0644]
README
build/.gitignore [new file with mode: 0644]
build/aquosa/.gitignore [new file with mode: 0644]
build/aquosa/Makefile [moved from Makefile with 100% similarity]
build/aquosa/Makefile.omk [new file with mode: 0644]
build/aquosa/Makefile.rules [new file with mode: 0644]
build/aquosa/config.target [new file with mode: 0644]
build/aquosa/create-links [new file with mode: 0755]
build/aquosa/fna [new symlink]
build/aquosa/forb [new symlink]
build/aquosa/fosa [new symlink]
build/aquosa/frsh [new symlink]
build/aquosa/frsh-forb-demo.sh [new file with mode: 0755]
build/aquosa/frsh-include [new symlink]
build/aquosa/fwp [new symlink]
build/aquosa/kernelcfg2mk [new file with mode: 0755]
build/aquosa/ulut [new symlink]
build/aquosa/wvtest/c/Makefile [moved from forb-idl/Makefile with 100% similarity]
build/aquosa/wvtest/c/Makefile.omk [new file with mode: 0644]
build/aquosa/wvtest/c/wvtest.c [new file with mode: 0644]
build/aquosa/wvtest/c/wvtest.h [new file with mode: 0644]
build/aquosa/wvtest/c/wvtestfrsh.c [new file with mode: 0644]
build/aquosa/wvtest/c/wvtestmain.c [new file with mode: 0644]
build/aquosa/wvtest/cpp/Makefile [moved from src/Makefile with 100% similarity]
build/aquosa/wvtest/cpp/Makefile.omk [new file with mode: 0644]
build/aquosa/wvtest/cpp/wvtest.cc [new file with mode: 0644]
build/aquosa/wvtest/cpp/wvtest.h [new file with mode: 0644]
build/aquosa/wvtest/cpp/wvtestmain.cc [new file with mode: 0644]
build/aquosa/wvtestrun [new symlink]
build/marte/Makefile [moved from src/tests/Makefile with 100% similarity]
build/marte/Makefile.omk [new file with mode: 0644]
build/marte/Makefile.rules [new file with mode: 0644]
build/marte/config.target [new file with mode: 0644]
build/marte/create-links [new file with mode: 0755]
doc/RelNotes-0.1.1.txt [new file with mode: 0644]
doc/RelNotes-0.1.txt [new file with mode: 0644]
scripts/reselase.sh [new file with mode: 0755]
src/forb/.gitignore [moved from .gitignore with 100% similarity]
src/forb/COPYING [moved from COPYING with 100% similarity]
src/forb/Doxyfile [moved from Doxyfile with 100% similarity]
src/forb/Makefile [moved from src/tests/object_to_string/Makefile with 100% similarity]
src/forb/Makefile.omk [moved from Makefile.omk with 100% similarity]
src/forb/README [new file with mode: 0644]
src/forb/TODO [moved from TODO with 100% similarity]
src/forb/doc/forb.vpp [moved from doc/forb.vpp with 100% similarity]
src/forb/forb-idl/Makefile [moved from src/tests/objref/Makefile with 100% similarity]
src/forb/forb-idl/Makefile.am [moved from forb-idl/Makefile.am with 100% similarity]
src/forb/forb-idl/Makefile.in [moved from forb-idl/Makefile.in with 100% similarity]
src/forb/forb-idl/Makefile.omk [moved from forb-idl/Makefile.omk with 100% similarity]
src/forb/forb-idl/Makefile.rules [moved from forb-idl/Makefile.rules with 100% similarity]
src/forb/forb-idl/ORBit-idl-2.0.pc.in [moved from forb-idl/ORBit-idl-2.0.pc.in with 100% similarity]
src/forb/forb-idl/config.h [moved from forb-idl/config.h with 100% similarity]
src/forb/forb-idl/forb-idl-backend.c [moved from forb-idl/forb-idl-backend.c with 100% similarity]
src/forb/forb-idl/forb-idl-backend.h [moved from forb-idl/forb-idl-backend.h with 100% similarity]
src/forb/forb-idl/forb-idl-c-backend.c [moved from forb-idl/forb-idl-c-backend.c with 100% similarity]
src/forb/forb-idl/forb-idl-c-backend.h [moved from forb-idl/forb-idl-c-backend.h with 100% similarity]
src/forb/forb-idl/forb-idl-c-common.c [moved from forb-idl/forb-idl-c-common.c with 100% similarity]
src/forb/forb-idl/forb-idl-c-deps.c [moved from forb-idl/forb-idl-c-deps.c with 100% similarity]
src/forb/forb-idl/forb-idl-c-headers.c [moved from forb-idl/forb-idl-c-headers.c with 100% similarity]
src/forb/forb-idl/forb-idl-c-imodule.c [moved from forb-idl/forb-idl-c-imodule.c with 100% similarity]
src/forb/forb-idl/forb-idl-c-skelimpl.c [moved from forb-idl/forb-idl-c-skelimpl.c with 100% similarity]
src/forb/forb-idl/forb-idl-c-skels.c [moved from forb-idl/forb-idl-c-skels.c with 100% similarity]
src/forb/forb-idl/forb-idl-c-stubs.c [moved from forb-idl/forb-idl-c-stubs.c with 100% similarity]
src/forb/forb-idl/forb-idl-c-typecode.c [moved from forb-idl/forb-idl-c-typecode.c with 100% similarity]
src/forb/forb-idl/forb-idl-c-utils.c [moved from forb-idl/forb-idl-c-utils.c with 100% similarity]
src/forb/forb-idl/forb-idl-driver.c [moved from forb-idl/forb-idl-driver.c with 100% similarity]
src/forb/forb-idl/forb-idl-main.c [moved from forb-idl/forb-idl-main.c with 100% similarity]
src/forb/forb-idl/forb-idl-utils.c [moved from forb-idl/forb-idl-utils.c with 100% similarity]
src/forb/forb-idl/forb-idl2.h [moved from forb-idl/forb-idl2.h with 100% similarity]
src/forb/forb-idl/forb-idl3-types.h [moved from forb-idl/forb-idl3-types.h with 100% similarity]
src/forb/forb-idl/forb_config.h [moved from forb-idl/forb_config.h with 100% similarity]
src/forb/src/Makefile [moved from tests-idl/Makefile with 100% similarity]
src/forb/src/Makefile.omk [moved from src/Makefile.omk with 100% similarity]
src/forb/src/basic_types.h [moved from src/basic_types.h with 100% similarity]
src/forb/src/cdr.c [moved from src/cdr.c with 100% similarity]
src/forb/src/cdr.h [moved from src/cdr.h with 100% similarity]
src/forb/src/cdr_codec.h [moved from src/cdr_codec.h with 100% similarity]
src/forb/src/daemon.c [moved from src/daemon.c with 100% similarity]
src/forb/src/discovery.c [moved from src/discovery.c with 100% similarity]
src/forb/src/discovery.h [moved from src/discovery.h with 100% similarity]
src/forb/src/exec_req.c [moved from src/exec_req.c with 100% similarity]
src/forb/src/exec_req.h [moved from src/exec_req.h with 100% similarity]
src/forb/src/executor.c [moved from src/executor.c with 100% similarity]
src/forb/src/executor.h [moved from src/executor.h with 100% similarity]
src/forb/src/forb-idl.idl [moved from src/forb-idl.idl with 100% similarity]
src/forb/src/forb-internal.h [moved from src/forb-internal.h with 100% similarity]
src/forb/src/forb.c [moved from src/forb.c with 100% similarity]
src/forb/src/forb.h [moved from src/forb.h with 100% similarity]
src/forb/src/forb_endian.h [moved from src/forb_endian.h with 100% similarity]
src/forb/src/forb_utils.h [moved from src/forb_utils.h with 100% similarity]
src/forb/src/iop-idl.idl [moved from src/iop-idl.idl with 100% similarity]
src/forb/src/iop.c [moved from src/iop.c with 100% similarity]
src/forb/src/iop.h [moved from src/iop.h with 100% similarity]
src/forb/src/object.c [moved from src/object.c with 100% similarity]
src/forb/src/object.h [moved from src/object.h with 100% similarity]
src/forb/src/object_type.h [moved from src/object_type.h with 100% similarity]
src/forb/src/peer.c [moved from src/peer.c with 100% similarity]
src/forb/src/peer.h [moved from src/peer.h with 100% similarity]
src/forb/src/port.c [moved from src/port.c with 100% similarity]
src/forb/src/port.h [moved from src/port.h with 100% similarity]
src/forb/src/proto.c [moved from src/proto.c with 100% similarity]
src/forb/src/proto.h [moved from src/proto.h with 100% similarity]
src/forb/src/proto_inet.c [moved from src/proto_inet.c with 100% similarity]
src/forb/src/proto_inet.h [moved from src/proto_inet.h with 100% similarity]
src/forb/src/proto_unix.c [moved from src/proto_unix.c with 100% similarity]
src/forb/src/proto_unix.h [moved from src/proto_unix.h with 100% similarity]
src/forb/src/refcnt.c [moved from src/refcnt.c with 100% similarity]
src/forb/src/refcnt.h [moved from src/refcnt.h with 100% similarity]
src/forb/src/regref.c [moved from src/regref.c with 100% similarity]
src/forb/src/regref.h [moved from src/regref.h with 100% similarity]
src/forb/src/request.c [moved from src/request.c with 100% similarity]
src/forb/src/request.h [moved from src/request.h with 100% similarity]
src/forb/src/server_id.h [moved from src/server_id.h with 100% similarity]
src/forb/src/sha1.c [moved from src/sha1.c with 100% similarity]
src/forb/src/sha1.h [moved from src/sha1.h with 100% similarity]
src/forb/src/syncobj.c [moved from src/syncobj.c with 100% similarity]
src/forb/src/syncobj.h [moved from src/syncobj.h with 100% similarity]
src/forb/src/tests/Makefile [new file with mode: 0644]
src/forb/src/tests/Makefile.omk [moved from src/tests/Makefile.omk with 100% similarity]
src/forb/src/tests/discovery.c [moved from src/tests/discovery.c with 100% similarity]
src/forb/src/tests/hello.idl [moved from src/tests/hello.idl with 100% similarity]
src/forb/src/tests/hello_impl.c [moved from src/tests/hello_impl.c with 100% similarity]
src/forb/src/tests/hello_impl.h [moved from src/tests/hello_impl.h with 100% similarity]
src/forb/src/tests/hello_inproc.c [moved from src/tests/hello_inproc.c with 100% similarity]
src/forb/src/tests/hello_remote.c [moved from src/tests/hello_remote.c with 100% similarity]
src/forb/src/tests/object_to_string/Makefile [new file with mode: 0644]
src/forb/src/tests/object_to_string/Makefile.omk [moved from src/tests/object_to_string/Makefile.omk with 100% similarity]
src/forb/src/tests/object_to_string/interface.idl [moved from src/tests/object_to_string/interface.idl with 100% similarity]
src/forb/src/tests/object_to_string/obj2str.c [moved from src/tests/object_to_string/obj2str.c with 100% similarity]
src/forb/src/tests/objref/Makefile [new file with mode: 0644]
src/forb/src/tests/objref/Makefile.omk [moved from src/tests/objref/Makefile.omk with 100% similarity]
src/forb/src/tests/objref/objref.c [moved from src/tests/objref/objref.c with 100% similarity]
src/forb/src/tests/objref/objref.idl [moved from src/tests/objref/objref.idl with 100% similarity]
src/forb/src/tests/regobjref.c [moved from src/tests/regobjref.c with 100% similarity]
src/forb/src/tests/sequence.c [moved from src/tests/sequence.c with 100% similarity]
src/forb/src/tests/sequence.idl [moved from src/tests/sequence.idl with 100% similarity]
src/forb/src/tests/test_proto_inet.c [moved from src/tests/test_proto_inet.c with 100% similarity]
src/forb/src/tests/test_proto_unix.c [moved from src/tests/test_proto_unix.c with 100% similarity]
src/forb/src/tests/test_syncobj.c [moved from src/tests/test_syncobj.c with 100% similarity]
src/forb/src/types.idl [moved from src/types.idl with 100% similarity]
src/forb/src/ul_log_domains [moved from src/ul_log_domains with 100% similarity]
src/forb/src/uuid.c [moved from src/uuid.c with 100% similarity]
src/forb/src/uuid.h [moved from src/uuid.h with 100% similarity]
src/forb/tests-idl/Makefile [new file with mode: 0644]
src/forb/tests-idl/Makefile.omk [moved from tests-idl/Makefile.omk with 100% similarity]
src/forb/tests-idl/enum.idl [moved from tests-idl/enum.idl with 100% similarity]
src/forb/tests-idl/example_client.c [moved from tests-idl/example_client.c with 100% similarity]
src/forb/tests-idl/example_server.c [moved from tests-idl/example_server.c with 100% similarity]
src/forb/tests-idl/myinterface.idl [moved from tests-idl/myinterface.idl with 100% similarity]
src/forb/tests-idl/sequence.idl [moved from tests-idl/sequence.idl with 100% similarity]
src/forb/tests-idl/string_test.idl [moved from tests-idl/string_test.idl with 100% similarity]
src/forb/tests-idl/struct.idl [moved from tests-idl/struct.idl with 100% similarity]
src/forb/tests-idl/typedef.idl [moved from tests-idl/typedef.idl with 100% similarity]
src/frsh-forb.el [new file with mode: 0644]
src/update-frescor-svn [new file with mode: 0755]
src/update-to-git-head [new file with mode: 0755]
src/wvtest.sh [new file with mode: 0755]

diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..8802737
--- /dev/null
@@ -0,0 +1,24 @@
+[submodule "src/forb"]
+       path = src/forb
+       url = ../forb
+[submodule "src/fwp"]
+       path = src/fwp
+       url = ../fwp
+[submodule "src/ulut"]
+       path = src/ulut
+       url = git://rtime.felk.cvut.cz/ulut.git
+[submodule "src/frsh-include"]
+       path = src/frsh-include
+       url = ../frsh-include
+[submodule "src/fna"]
+       path = src/fna
+       url = ../fna
+[submodule "src/fosa"]
+       path = src/fosa
+       url = ../fosa
+[submodule "src/frsh"]
+       path = src/frsh
+       url = ../frsh
+[submodule "src/wvtest"]
+       path = src/wvtest
+       url = git://rtime.felk.cvut.cz/wvtest.git
diff --git a/README b/README
index f6969c040433e895b6a2d8957a86e3e2a85094fc..68d2b820b4a23b4ecaf2ef93c05571f7c511a6f5 100644 (file)
--- a/README
+++ b/README
-Compilation
-===========
+* FRSH/FORB FRAMEWORK
 
-1. Download FRESCOR SVN repositories fosa and omk-build
+  FRSH/FORB is a contract-based resource reservation framework for
+  distributed real-time applications. In general, it provides timing
+  isolation between applications, i.e. multiple applications can use
+  the same resources such as CPU, networks, etc., without influencing
+  timing of the other applications. The main principle is that
+  application developers use FRSH API to specify their resource
+  requirements needed to achieve desired timeliness and the framework
+  uses schedulability analysis to check these requirements. If the
+  check is successful an application is granted a "virtual resource"
+  which allow the application to use the requested resource while
+  enforcing the application not to use more than requested.
 
-2. Download ulut (from
-   http://sourceforge.net/project/showfiles.php?group_id=118937&package_id=130840)
+  The development of the framework begun in FRESCOR project
+  (http://frescor.org) and now it is developed as a stand-alone
+  project on SourceForge (http://frsh-forb.sf.net).
 
-3. Create symbolic links to forb, fosa and ulut sources inside
-   omk-build/aquosa:
+* BUILDING FRSH/FORB FRAMEWORK
 
-   cd omk-build/aquosa
-   ln -s some-path/fosa .
-   ln -s some-path/ulut .
-   ln -s path-to-this-directory/forb .
+1) Initialize and download additional submodules:
+   
+   git submodule init
+   git submodule update
 
-3. Configure the sources:
-       make default-config
+2) Install prerequisites. On Debian/Ubuntu:
 
-5. Compile it:
-       make    
-       
+     apt-get install libidl-dev libcpufreq-dev libacpi-dev \
+                    libcgroup-dev libncurses5-dev
+
+   To build camera demo, you need to:
+
+     apt-get install freeglut3-dev
+
+3) Go to build directory and configure the build:
+   
+   cd build/aquosa
+   make default-config
+
+   If you are not satisfied with configuration found in
+   config.omk-default or config.target, you can override it in
+   config.omk.
+
+   To be able to use CPU reservations AQuoSA
+   (http://aquosa.sourceforge.net) has to be installed. If you cannot
+   use AQuoSA, the framework can also be compiled without CPU support
+   (echo CONFIG_AQUOSA=n >> config.omk) or can use cgroups (echo
+   CONFIG_CPUCG=y >> config.omk). Note, that cgroups support is not
+   well tested, but we plan to work on it.
+
+4) Compile it:
+
+   make
+
+5) Test it:
+
+   ./_compiled/bin/fcb &
+   ./_compiled/bin/frm_dummy &
+   ./_compiled/bin/frm_gui &
+   ./_compiled/bin-tests/dummy_renegotiation
+
+* DIRECTORY STRUCTURE
+
+  * build/* - configuration for different build targets
+
+  * build/aquosa - default build for linux
+
+  * build/marte - build for MarteOS. Not completely supported now.
+
+  * src - all sources
+
+  * src/forb - CORBA-like middle for interprocess and inter-node
+    communication.
+
+  * src/frsh - The core of resource reservation framework.
+
+  * src/frsh-include - FRSH API headers from FRESCOR project. Our FRSH
+    framework implements this API.
+
+  * src/fosa - Operating system adaptation layer
+
+  * src/ulut - library providing generic data types and algorithms
+    (AVL trees etc.).
+
+  * src/fna - Network adaptation layer = unified API for plugging in
+    different network protocols.
+
+  * src/fwp - Communication protocol and resource management for WiFi
+    (also works with Ethernet).
+
+* OLD HOWTO - may be out of date
+
+    Linux + AQuoSA
+
+     * Install AQuoSA (http://aquosa.sourceforge.net)
+     * $HOME/frescor/src/omk-build/aquosa
+     * Adjust symlinks to FRESCOR modules (fosa, frsh, utils, ...) or use ./create-links script
+     * Create config.omk containing (or use a shell variable in your .bashrc)
+
+  AQUOSA_ROOT=/path/to/aquosa/install/path
+
+     * Actually, my preferred way of working is adding the following
+       variables in .bashrc:
+
+  # AQuoSA environment
+  export AQUOSA_ROOT=/usr/local/aquosa
+  export PATH="$PATH:$AQUOSA_ROOT/bin"
+  export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$AQUOSA_ROOT/lib"
+  # FRESCOR environment
+  export PLATFORM=AQuoSA
+  export FOSA_ROOT=$HOME/path/to/fosa
+  export FRSH_ROOT=$HOME/path/to/frsh
+  export UTILS_ROOT=$HOME/path/to/utils
+  LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$FOSA_ROOT/lib:$FRSH_ROOT/lib:$UTILS_ROOT/lib"
+  # OMK environment
+  # Use `omk' for OMK-enabled sources
+  alias omk="make -f $HOME/path/to/Makefile.rules"
+  # link headers instead of copying them
+  export LN_HEADERS=y
+
+     * Create default-configuration by running
+
+  make default-config
+
+     * Run
+
+  make
+
+** Further remarks
+
+- If we are not interested in compilation of some component (because
+  it is currently in uncompilable state), we can simply delete the
+  link to it.
+
+- It might be possible that you will need to change some configuration
+  value from config.target. You can override any variable declared
+  there in config.omk. For example, if you have MARTE installed in a
+  different directory that the one specified in config.target, you can
+  put the following in config.omk:
+
+  MARTE_PATH=/path/to/marte/
+
+- To compile the FRESCOR for Marte, it is not necessary to set PATH
+  variable to GNAT compiler since OMK uses full paths to call the
+  compiler.
+
+- Since there are many things in uncompilable state, you may want to
+  use `make -k' to ignore compilation errors.
+
+- Since we don't want to modify the original Makefiles, in order to
+  compile only a part of the tree, you cannot simply run make in the
+  desired directory, but you have to specify -f flag with the path to
+  Makefile.rules. For this reason, we recommend defining the following
+  alias:
+
+  alias omk="make -f $HOME/frescor/src/omk-build/marte/Makefile.rules"
+
+** Why is OMK good for FRESCOR
+
+     * It is not easy to test FRESCOR simultaneously on multiple platforms.
+       With OMK, you can have the same sources compiled for multiple
+       platforms/targets at the same time because it uses out of source
+       directory compilation.
+     * Dependencies are not handled correctly in current Makefiles. For
+       example headers (in most tests) and some libraries (fosa_xxx) are not
+       specified as dependencies. OMK handles dependencies automatically, so
+       developers don't have to care about them.
+     * With OMK it is easy to combine multiple components/libraries (from
+       different developers) together and compile them with the same
+       configuration (e.g. PLATFORM variable). The structure of leaf
+       makefiles (Makefile for every component) is very simple and *well
+       specified*. Because of this it is easy to combine components from
+       multiple developers.
+     * Directory structure for compilation with current makefiles must be
+       fixed. In makefiles there is many "..". This prevents the use of
+       symbolic links to create desired directory structure because make
+       always treats ".." physically (i.e. it don't respect the directory
+       structure created by symbolic links). In OMK, the position of
+       directories in the source tree is not important. This is another
+       reason, why integration is simpler with OMK.
+     * OMK already supports compilation for user-space programs/libraries,
+       Linux and RTLinux modules, RTEMS and several other platforms. Now we
+       have also added support for Marte. It works under MinGW and Cygwin, so
+       it can be used to compile for OSE. In Pisa, they already use OMK for
+       Aquosa.
+
+** FAQ
+
+- How do I debug my Makefile.omk set-up ?
+
+   Just activate verbose compilation (V=1 or V=2):
+
+  make -f /path/to/Makefile.rules binary-pass V=1
+
+- How do I get back syntax highlighting in Emacs while editing .omk files ?
+
+   Just add these lines to your $(HOME)/.emacs:
+
+  (setq auto-mode-alist
+    (append '(("\.omk$"  . makefile-mode))
+      auto-mode-alist))
diff --git a/build/.gitignore b/build/.gitignore
new file mode 100644 (file)
index 0000000..3466337
--- /dev/null
@@ -0,0 +1,4 @@
+_compiled/
+_build/
+config.omk-default
+config.omk
diff --git a/build/aquosa/.gitignore b/build/aquosa/.gitignore
new file mode 100644 (file)
index 0000000..bcb062a
--- /dev/null
@@ -0,0 +1,2 @@
+cscope.files
+cscope.out
similarity index 100%
rename from Makefile
rename to build/aquosa/Makefile
diff --git a/build/aquosa/Makefile.omk b/build/aquosa/Makefile.omk
new file mode 100644 (file)
index 0000000..7bc274f
--- /dev/null
@@ -0,0 +1,3 @@
+SUBDIRS=$(ALL_OMK_SUBDIRS) wvtest/c
+EXTRA_RULES_SUBDIRS = forb/forb-idl
+
diff --git a/build/aquosa/Makefile.rules b/build/aquosa/Makefile.rules
new file mode 100644 (file)
index 0000000..12aace8
--- /dev/null
@@ -0,0 +1,1424 @@
+#  Makefile.rules - OCERA make framework common project rules -*- makefile-gmake -*- #OMK:base.omk
+#
+#  (C) Copyright 2003, 2006, 2007, 2008, 2009  by Pavel Pisa - OCERA team member
+#  (C) Copyright 2006, 2007, 2008, 2009, 2010 by Michal Sojka - Czech Technical University, FEE, DCE
+#
+#  Homepage: http://rtime.felk.cvut.cz/omk/
+#  Version:  0.2-29-gac7ec3c
+#
+# The OMK build system is distributed under the GNU General Public
+# License.  See file COPYING for details.
+#
+#
+#                   Version for Linux/RTLinux builds.                            #OMK:linux.omk
+#
+#
+# input variables                                                                #OMK:base.omk
+# V                .. if set to 1, full command text is shown else short form is used
+# W                .. whole tree - if set to 1, make is always called from the top-level directory
+# SUBDIRS          .. list of subdirectories intended for make from actual directory
+# default_CONFIG   .. list of default config assignments CONFIG_XXX=y/n ...
+# wvtest_SCRIPTS    .. list of scripts producing wvtest output                   #OMK:wvtest.omk
+# wvtest_PROGRAMS   .. list of the testing programs producing wvtest output
+# LN_HEADERS       .. if "y", header files are symbolicaly linked instead of copied. #OMK:include.omk
+# input variables                                                                #OMK:linux.omk
+# lib_LIBRARIES    .. list of the user-space libraries
+# shared_LIBRARIES .. list of the user-space shared libraries
+# kernel_LIBRARIES .. list of the kernel-space libraries
+# rtlinux_LIBRARIES.. list of the RT-Linux kernel-space libraries
+# include_HEADERS  .. list of the user-space public header files
+# nobase_include_HEADERS .. public headers copied even with directory part
+# renamed_include_HEADERS .. public headers copied to the different target name
+# kernel_HEADERS   .. list of the kernel-space public header files
+# rtlinux_HEADERS  .. list of the RT-Linux kernel-space public header files
+# bin_PROGRAMS     .. list of the require binary programs
+# utils_PROGRAMS   .. list of the development utility programs
+# test_PROGRAMS    .. list of the testing programs
+# kernel_MODULES   .. list of the kernel side modules/applications
+# rtlinux_MODULES  .. list of RT-Linux the kernel side modules/applications
+# xxx_SOURCES      .. list of specific target sources
+# xxx_LIBS         .. list of specific target libraries (-l prefix is automatically added)
+# xxx_LDFLAGS      .. list of specific target LDFLAGS
+# lib_LOADLIBES    .. list of libraries linked to each executable
+# INCLUDES         .. additional include directories and defines for user-space
+# kernel_INCLUDES  .. additional include directories and defines for kernel-space
+# rtlinux_INCLUDES .. additional include directories and defines for RT-Linux
+# OMIT_KERNEL_PASSES  if defined, all kernel passes are omited
+#
+# LINUX_DIR        .. location of Linux kernel sources
+# RTL_DIR          .. location of RT-Linux sources
+# CFLAGS           .. C compiler flags
+# CXXFLAGS         .. C++ compiler flags
+# CPPFLAGS        .. C preprocessor flags
+# LDFLAGS         .. linker flags for programs linking
+# LOCAL_CONFIG_H   .. name of local config.h file generated from values          #OMK:config_h.omk
+#                     of options defined in the current directory
+# config_include_HEADERS .. names of global config files (possibly
+#                     with subdirectories)
+# xxx_DEFINES      .. list of config directives to be included in
+#                     config header file of the name <somedir>/xxx.h
+# DOXYGEN          .. if non-empty, generated headers includes Doxygen's @file
+#                    command, so it is possible to document config
+#                    variables.
+# QT_PROJECTS     .. list of QT .pro file to use for compilation                  #OMK:qt.omk
+# QT_SUBDIRS       .. subdirectories where to build QT applications using qmake (depricated)
+# QTDIR                   .. where QT resides
+OMK_RULES_TYPE=linux                                                             #OMK:Makefile.rules.linux@
+                                                                                 #OMK:base.omk@Makefile.rules.linux
+# If we are not called by OMK leaf Makefile...
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(abspath $(dir $(filter %Makefile.rules,$(MAKEFILE_LIST))))
+endif
+
+# OUTPUT_DIR is the place where _compiled, _build and possible other
+# files/directories are created. By default is the same as
+# $(MAKERULES_DIR).
+ifndef OUTPUT_DIR
+OUTPUT_DIR := $(MAKERULES_DIR)
+endif
+
+# We need to ensure definition of sources directory first
+ifndef SOURCES_DIR
+# Only shell built-in pwd understands -L
+SOURCES_DIR := $(shell ( pwd -L ) )
+INVOCATION_DIR := $(SOURCES_DIR:$(OUTPUT_DIR)%=%)
+INVOCATION_DIR := $(INVOCATION_DIR:/%=%)
+INVOCATION_DIR := $(INVOCATION_DIR:\\%=%)
+endif
+
+.PHONY: all default check-make-ver print-hints omkize
+
+ifdef W
+  ifeq ("$(origin W)", "command line")
+    OMK_WHOLE_TREE:=$(W)
+  endif
+endif
+ifndef OMK_WHOLE_TREE
+  OMK_WHOLE_TREE:=0
+endif
+
+ifneq ($(OMK_WHOLE_TREE),1)
+all: check-make-ver print-hints default
+       @echo "Compilation finished"
+else
+# Run make in the top-level directory
+all:
+       @$(MAKE) -C $(MAKERULES_DIR) OMK_SERIALIZE_INCLUDED=n SOURCES_DIR=$(MAKERULES_DIR) RELATIVE_DIR="" $(MAKECMDGOALS) W=0
+endif
+
+ifdef OMK_TESTSROOT
+# Usage: $(call canttest,<error message>)
+define canttest
+       ( echo "$(1)" > $(OUTPUT_DIR)/_canttest; echo "$(1)"; exit 1 )
+endef
+else
+define canttest
+       echo "$(1)"
+endef
+endif
+
+#=========================
+# Include the config file
+
+ifndef CONFIG_FILE
+CONFIG_FILE      := $(OUTPUT_DIR)/config.omk
+endif
+
+$(CONFIG_FILE)-default:
+       $(MAKE) default-config 
+
+ifeq ($(MAKECMDGOALS),default-config)
+export DEFAULT_CONFIG_PASS=1
+endif
+
+ifneq ($(DEFAULT_CONFIG_PASS),1)
+include $(CONFIG_FILE)-default
+endif
+
+-include $(OUTPUT_DIR)/config.target
+
+ifneq ($(wildcard $(CONFIG_FILE)),)
+-include $(CONFIG_FILE)
+endif
+
+
+CONFIG_FILES ?= $(wildcard $(CONFIG_FILE)-default) $(wildcard $(OUTPUT_DIR)/config.target) $(wildcard $(CONFIG_FILE))
+
+
+export SOURCES_DIR MAKERULES_DIR RELATIVE_DIR INVOCATION_DIR
+export CONFIG_FILE CONFIG_FILES OMK_SERIALIZE_INCLUDED OMK_VERBOSE OMK_SILENT
+# OMK_SERIALIZE_INCLUDED has to be exported to submakes because passes
+# must to be serialized only in the toplevel make.
+
+ifndef RELATIVE_DIR
+RELATIVE_DIR := $(SOURCES_DIR:$(OUTPUT_DIR)%=%)
+endif
+#$(warning  === RELATIVE_DIR = "$(RELATIVE_DIR)" ===)
+override RELATIVE_DIR := $(RELATIVE_DIR:/%=%)
+override RELATIVE_DIR := $(RELATIVE_DIR:\\%=%)
+#$(warning  RELATIVE_DIR = "$(RELATIVE_DIR)")
+#override BACK2TOP_DIR := $(shell echo $(RELATIVE_DIR)/ | sed -e 's_//_/_g' -e 's_/\./_/_g' -e 's_^\./__g'  -e 's_\([^/][^/]*\)_.._g' -e 's_/$$__')
+#$(warning  BACK2TOP_DIR = "$(BACK2TOP_DIR)")
+
+#$(warning SOURCES_DIR = "$(SOURCES_DIR)")
+#$(warning MAKERULES_DIR = "$(OUTPUT_DIR)")
+#$(warning RELATIVE_DIR = "$(RELATIVE_DIR)")
+
+# We have to use RELATIVE_PREFIX because of mingw
+override RELATIVE_PREFIX := $(RELATIVE_DIR)/
+override RELATIVE_PREFIX := $(RELATIVE_PREFIX:/%=%)
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+# Define srcdir for Automake compatibility
+srcdir = $(SOURCES_DIR)
+
+# Defines for quiet compilation
+ifdef V
+  ifeq ("$(origin V)", "command line")
+    OMK_VERBOSE = $(V)
+  endif
+endif
+ifndef OMK_VERBOSE
+  OMK_VERBOSE = 0
+endif
+ifneq ($(OMK_VERBOSE),0)
+  Q =
+else
+  Q = @
+endif
+ifneq ($(findstring s,$(MAKEFLAGS)),)
+  QUIET_CMD_ECHO = true
+  OMK_SILENT = 1
+else
+  QUIET_CMD_ECHO = echo
+endif
+
+MAKEFILE_OMK=Makefile.omk
+# All subdirectories (even linked ones) containing Makefile.omk
+# Usage in Makefile.omk: SUBDIRS = $(ALL_OMK_SUBDIRS)
+ALL_OMK_SUBDIRS = $(patsubst %/$(MAKEFILE_OMK),%,$(patsubst $(SOURCES_DIR)/%,%,$(wildcard $(SOURCES_DIR)/*/$(MAKEFILE_OMK))))
+
+# ===================================================================
+# We have set up all important variables, so we can check and include
+# real OCERA style Makefile.omk now
+ifndef OMK_INCLUDED
+include $(SOURCES_DIR)/$(MAKEFILE_OMK)
+ifeq ($(AUTOMATIC_SUBDIRS),y)
+SUBDIRS?=$(ALL_OMK_SUBDIRS)
+endif
+OMK_INCLUDED := 1
+endif
+
+print-hints:
+       @echo 'Use "make V=1" to see the verbose compile lines.'
+
+check-make-ver:
+       @GOOD_MAKE_VERSION=`echo $(MAKE_VERSION) | sed -n -e 's/^[4-9]\..*\|^3\.9[0-9].*\|^3\.8[1-9].*/y/p'` ; \
+       if [ x$$GOOD_MAKE_VERSION != xy ] ; then \
+               echo "Your make program version is too old and does not support OMK system." ; \
+               echo "Please update to make program 3.81beta1 or newer." ; exit 1 ; \
+       fi
+
+distclean dist-clean:
+       @$(QUIET_CMD_ECHO) "  RM      $(COMPILED_DIR_NAME) $(BUILD_DIR_NAME)"
+       @rm -fr $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)  $(OUTPUT_DIR)/$(BUILD_DIR_NAME)
+
+# Common OMK templates
+# ====================
+
+# Syntax: $(call mkdir,<dir name>)
+define mkdir_def
+       [ -d $(1) ] || mkdir -p $(1) || exit 1
+endef
+
+ifneq ($(OMK_VERBOSE),2)
+NO_PRINT_DIRECTORY := --no-print-directory
+endif
+
+ifeq ($(USE_LEAF_MAKEFILES),n)
+export USE_LEAF_MAKEFILES
+SUBDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+SOURCESDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+else
+SUBDIR_MAKEFILE=$(SOURCES_DIR)/$(3)/Makefile
+SOURCESDIR_MAKEFILE=$(SOURCES_DIR)/Makefile
+endif
+
+pass = $(strip $(1))
+
+unexport SUBDIRS
+
+# Call a pass in a subdirectory
+# Usage: $(call omk_pass_subdir_template,<pass name>,<build dir>,<subdir>)
+define omk_pass_subdir_template
+.PHONY: $(pass)-$(3)-subdir
+$(pass)-submakes: $(pass)-$(3)-subdir
+$(pass)-$(3)-subdir: MAKEOVERRIDES:=$(filter-out SUBDIRS=%,$(MAKEOVERRIDES))
+$(pass)-$(3)-subdir:
+       @$(call mkdir_def,$(2)/$(3))
+       +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(3) $(NO_PRINT_DIRECTORY) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(3) -C $(2)/$(3) \
+               -f $(SUBDIR_MAKEFILE) $(pass)-submakes
+# In subdirectories we can call submakes directly since passes are
+# already serialized on the toplevel make.
+endef
+
+ifdef OMK_TESTSROOT
+check-target = $(1:%=%-check)
+endif
+
+# Call a pass in a subdirectory
+# Usage: $(call extra_rules_subdir_template,<subdir>)
+define extra_rules_subdir_template
+extra-rules-subdirs: extra-rules-$(1)
+extra-rules-$(1):
+       +@$(MAKE) OMK_SERIALIZE_INCLUDED=n MAKERULES_DIR=$(SOURCES_DIR)/$(1) OUTPUT_DIR=$(OUTPUT_DIR) \
+               SOURCES_DIR=$(SOURCES_DIR)/$(1) RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) -C $(SOURCES_DIR)/$(1)
+endef
+
+.PHONY: extra-rules-subdirs
+extra-rules-subdirs:
+
+$(foreach subdir,$(EXTRA_RULES_SUBDIRS),$(eval $(call extra_rules_subdir_template,$(subdir))))
+
+# Usage: $(call omk_pass_template,<pass name>,<build dir>,[<local make flags>],[<local enable condition>])
+define omk_pass_template
+.PHONY: $(pass) $(pass)-local $(pass)-check $(pass)-submakes
+$(foreach subdir,$(SUBDIRS),$(eval $(call omk_pass_subdir_template,$(pass),$(2),$(subdir))))
+$(pass):
+# Submakes have to be called this way and not as dependecies for pass
+# serialization to work
+       +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR) $(NO_PRINT_DIRECTORY) \
+               RELATIVE_DIR=$(RELATIVE_DIR) \
+               -f $(SOURCESDIR_MAKEFILE) $(pass)-submakes
+$(pass)-submakes:
+       @true                   # Do not emit "nothing to be done" messages
+
+ifneq ($(4)$($(pass)_HOOKS),)
+$(pass)-submakes: $(pass)-this-dir
+$(pass)-this-dir: $(foreach subdir,$(SUBDIRS),$(pass)-$(subdir)-subdir)
+       +@echo "make[omk]: $(pass) in $(RELATIVE_DIR)"
+       @$(call mkdir_def,$(2))
+       +@$(MAKE) $(NO_PRINT_DIRECTORY) SOURCES_DIR=$(SOURCES_DIR) RELATIVE_DIR=$(RELATIVE_DIR) -C $(2) \
+               -f $(SOURCESDIR_MAKEFILE) $(3) $(check-target) $(1:%=%-local)
+$(pass)-local: $($(pass)_HOOKS)
+endif
+endef
+
+# =======================
+# DEFAULT CONFIG PASS
+
+default-config:
+       @echo "# Start of OMK config file" > "$(CONFIG_FILE)-default"
+       @echo "# This file should not be altered manually" >> "$(CONFIG_FILE)-default"
+       @echo "# Overrides should be stored in file $(notdir $(CONFIG_FILE))" >> "$(CONFIG_FILE)-default"
+       @echo >> "$(CONFIG_FILE)-default"
+       @$(MAKE) $(NO_PRINT_DIRECTORY) -C $(OUTPUT_DIR) \
+               RELATIVE_DIR="" SOURCES_DIR=$(OUTPUT_DIR) \
+               -f $(OUTPUT_DIR)/Makefile default-config-pass
+
+$(eval $(call omk_pass_template,default-config-pass,$$(LOCAL_BUILD_DIR),,always))
+
+default-config-pass-local:
+#      @echo Default config for $(RELATIVE_DIR)
+       @echo "# Config for $(RELATIVE_DIR)" >> "$(CONFIG_FILE)-default"
+       @$(foreach x, $(default_CONFIG), echo '$(x)' | \
+               sed -e 's/^[^=]*=x$$/#\0/' >> "$(CONFIG_FILE)-default" ; )
+
+
+omkize:
+       $(Q)if ! grep -q MAKERULES_DIR Makefile; then \
+          echo "Makefile is not OMK leaf makefile!" >&2; exit 1; \
+       fi
+       $(Q)for i in `find -L . -name Makefile.omk` ; do \
+          d=`dirname $${i}`; \
+          if ! test -f "$${d}/Makefile.rules" && ( test -f "$${d}/Makefile" && ! cmp --silent Makefile "$${d}/Makefile" ); then \
+             rm -f "$${d}/Makefile"; \
+             cp -v Makefile "$${d}/Makefile"; \
+          fi \
+       done
+                                                                                 #OMK:wvtest.omk@Makefile.rules.linux
+# Documentation: wvtest_PROGRAMS is equivalent to test_PROGRAMS. The
+# difference is that it is automatically run during "make wvtest".
+test_PROGRAMS += $(wvtest_PROGRAMS)
+
+# Documentation: If your project uses wvtest, it is recomended to put
+# the "test: wvtest" rule to config.target.
+wvtest:
+       $(Q)$(MAKERULES_DIR)/wvtestrun $(MAKE) wvtest-pass
+
+.PHONY: wvtest
+
+$(eval $(call omk_pass_template,wvtest-pass,$$(LOCAL_BUILD_DIR),,$(wvtest_SCRIPTS)$(wvtest_PROGRAMS)))
+
+# Usage: $(call wvtest_template,<shell command>)
+define wvtest_template
+wvtest-pass-local: wvtest-run-$(1)
+.PHONY: wvtest-run-$(1)
+wvtest-run-$(1):
+       mkdir -p $(1).wvtest
+       cd $(1).wvtest && $(1)
+endef
+
+# Documentation: Write the test so, that it can be run from arbitrary
+# directory, i.e. in case of a script ensure that the wvtest library
+# is sourced like this:
+#
+# . $(dirname $0)/wvtest.sh
+
+$(foreach script,$(wvtest_SCRIPTS),$(eval $(call wvtest_template,$(SOURCES_DIR)/$(script))))
+# Hack!!!
+USER_TESTS_DIR := $(OUTPUT_DIR)/_compiled/bin-tests
+$(foreach prog,$(wvtest_PROGRAMS),$(eval $(call wvtest_template,$(USER_TESTS_DIR)/$(prog))))
+ifeq ($(OMK_VERBOSE),1)                                                          #OMK:include.omk@Makefile.rules.linux
+CPHEADER_FLAGS += -v
+LNHEADER_FLAGS += -v
+endif
+
+ifneq ($(LN_HEADERS),y)
+define cp_cmd
+if ! cmp --quiet $(1) $(2); then \
+    echo "  CP      $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; \
+    install -C -D $(CPHEADER_FLAGS) $(1) $(2) || exit 1; \
+fi
+endef
+else
+define cp_cmd
+if ! cmp --quiet $(1) $(2); then \
+    echo "  LN      $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; \
+    if [ -f $(1) ]; then d=$(2); mkdir -p $${d%/*} && ln -sf $(LNHEADER_FLAGS) $(1) $(2) || exit 1; else exit 1; fi; \
+fi
+endef
+endif
+
+# TODO: Check modification date of changed header files. If it is
+# newer that in source dir, show a warning.
+
+# Syntax: $(call include-pass-template,<include dir>,<keyword>)
+define include-pass-template
+include-pass-local: include-pass-local-$(2)
+include-pass-local-$(2): $$($(2)_GEN_HEADERS) $$(foreach f,$$(renamed_$(2)_GEN_HEADERS),$$(shell f='$$(f)'; echo $$$${f%->*}))
+       @$$(foreach f, $$($(2)_HEADERS),$$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(notdir $$(f))); )
+# FIXME: Use correct build dir, then document it (in the line bellow)
+       @$$(foreach f, $$($(2)_GEN_HEADERS),$$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$(f),$(1)/$$(notdir $$(f))); )
+       @$$(foreach f, $$(nobase_$(2)_HEADERS), $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(f)); )
+       @$$(foreach f, $$(renamed_$(2)_HEADERS), \
+          f='$$(f)'; srcfname=$$$${f%->*}; destfname=$$$${f#*->}; \
+          $$(call cp_cmd,$$(SOURCES_DIR)/$$$${srcfname},$(1)/$$$${destfname}); )
+       @$$(foreach f, $$(renamed_$(2)_GEN_HEADERS), \
+          f='$$(f)'; srcfname=$$$${f%->*}; destfname=$$$${f#*->}; \
+          $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$$${srcfname},$(1)/$$$${destfname}); )
+# Suppress "Nothing to be done for `include-pass-local'" message if no headers are defined in Makefile.omk
+       @$$(if $$($(2)_HEADERS)$$($(2)_GEN_HEADERS)$$(nobase_$(2)_HEADERS)$$(renamed_$(2)_HEADERS)$$(renamed_$(2)_GEN_HEADERS),,true)
+endef
+                                                                                 #OMK:linux.omk@Makefile.rules.linux
+# Hack to check RT-Linux rules
+#LINUX_DIR := /home/cvs/ocera/ocera-build/kernel/linux
+#RTL_DIR := /home/cvs/ocera/ocera-build/kernel/rtlinux
+#CONFIG_RTLINUX = y
+#OCERA_DIR := $(shell ( cd -L $(OUTPUT_DIR)/../../.. ; pwd -L ) )
+
+-include $(OUTPUT_DIR)/OCERA_TOP_DIR
+
+BUILD_DIR_NAME = _build
+COMPILED_DIR_NAME = _compiled
+ifndef GROUP_DIR_NAME
+GROUP_DIR_NAME = nogroup
+endif
+
+ifdef OCERA_DIR
+ifeq ($(wildcard $(OCERA_DIR)/ocera.mk),)
+$(warning "ocera.mk" file does not exist. Adapt Makefile.rules for standalone compilation)
+$(warning (comment out definition of OCERA_DIR line and optionally select RTL_DIR) )
+$(error or go to the ocera/ directory and do 'make' to generate the "ocera.mk" file first, please)
+endif
+include $(OCERA_DIR)/ocera.mk
+KERN_INCLUDE_DIR := $(OCERA_KERNEL_INCLUDES_DIR)
+KERN_LIB_DIR     := $(OCERA_KERNEL_LIBRARIES_DIR)
+KERN_MODULES_DIR := $(OCERA_MODULES_DIR)
+KERN_BUILD_DIR   := $(BUILD_DIR)/kern/$(GROUP_DIR_NAME)
+KERN_MODPOST_DIR := $(BUILD_DIR)/kern-modpost
+USER_INCLUDE_DIR := $(OCERA_USER_INCLUDES_DIR)
+USER_LIB_DIR     := $(OCERA_USER_LIBRARIES_DIR)
+USER_UTILS_DIR   := $(TARGET_DIR)/usr/bin
+USER_TESTS_DIR   := $(TARGET_DIR)/usr/bin
+USER_BIN_DIR     := $(TARGET_DIR)/usr/bin
+USER_BUILD_DIR   := $(BUILD_DIR)/user/$(GROUP_DIR_NAME)
+#LINUX_DIR        := $(OCERA_DIR)/kernel/linux
+#RTL_DIR          := $(OCERA_DIR)/kernel/rtlinux
+#CONFIG_FILE      := $(OCERA_DIR)/emdebsys/.config 
+ifneq ($(wildcard $(CONFIG_FILE)),)
+CONFIG_FILE_OK = y
+endif
+else # OCERA_DIR
+KERN_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include-kern
+KERN_LIB_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib-kern
+KERN_MODULES_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/modules
+KERN_BUILD_DIR   := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern
+KERN_MODPOST_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern-modpost
+USER_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include
+USER_LIB_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib
+USER_UTILS_DIR   := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-utils
+USER_TESTS_DIR   := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-tests
+USER_BIN_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin
+USER_BUILD_DIR   := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/user
+
+ifndef LINUX_VERSION
+LINUX_VERSION=$(shell uname -r)
+endif
+ifndef LINUX_DIR
+LINUX_DIR=/lib/modules/$(LINUX_VERSION)/build
+endif
+endif # OCERA_DIR
+
+ifeq ($(BUILD_OS),)
+  # Check for target
+  ifeq ($(OS),Windows_NT)
+    BUILD_OS := win32
+  else
+    BUILD_OS := $(shell uname | tr '[A-Z]' '[a-z]' )
+    #$(warning BUILD_OS=$(BUILD_OS))
+  endif
+endif
+
+ifeq ($(TARGET_OS),)
+  TARGET_OS := $(BUILD_OS)
+endif
+
+export TARGET_OS
+export BUILD_OS
+
+LOCAL_BUILD_DIR  = $(USER_OBJS_DIR)
+
+# Assign default values to CFLAGS variable. If the variable is defined
+# earlier (i.g. in config.omk), it is not overriden here.
+CFLAGS ?= -O2 -Wall
+CXXFLAGS ?= -O2 -Wall
+
+
+CPPFLAGS  += -I $(USER_INCLUDE_DIR)
+
+LOADLIBES += -L$(USER_LIB_DIR) 
+
+LOADLIBES += $(lib_LOADLIBES:%=-l%)
+
+LIB_CPPFLAGS += $(CPPFLAGS)
+LIB_CFLAGS   += $(CFLAGS)
+
+ifeq ($(TARGET_OS),win32)
+  EXE_SUFFIX = .exe
+  SOLIB_EXT = dll
+else
+  SOLIB_EXT = so
+  SOLIB_PICFLAGS += -fpic
+endif
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+USER_OBJS_DIR = $(USER_BUILD_DIR)/$(RELATIVE_DIR)
+KERN_OBJS_DIR = $(KERN_BUILD_DIR)/$(RELATIVE_DIR)
+OMK_WORK_DIR  = $(USER_OBJS_DIR)
+
+.PHONY: dep subdirs clean clean-custom cleandepend check-dir
+
+# Some support to serialize some targets for parallel make
+ifneq ($(OMK_SERIALIZE_INCLUDED),y)
+include-pass: check-dir
+library-pass: include-pass
+link-pseudo-pass: library-pass
+binary-pass: link-pseudo-pass
+kernel-lib-pass: include-pass
+kernel-mod-pass: kernel-lib-pass
+kernel-modpost-pass: kernel-mod-pass
+kernel-pass: kernel-mod-pass kernel-modpost-pass
+
+override OMK_SERIALIZE_INCLUDED = y
+MAKEOVERRIDES := $(filter-out OMK_SERIALIZE_INCLUDED=n,$(MAKEOVERRIDES))
+endif
+
+# Checks for OMK tester
+ifdef OMK_TESTSROOT
+default-config-pass-check include-pass-check:
+library-pass-check binary-pass-check:
+       @[ -x "$(shell which $(CC))" ] || $(call canttest,Cannot find compiler: $(CC))
+endif
+
+#=====================================================================
+# User-space rules and templates to compile programs, libraries etc.
+
+ifdef USER_RULE_TEMPLATES
+
+USER_SOURCES2OBJS = .o/.c .o/.cc .o/.cxx .o/.S .o/.o
+
+USER_SOURCES2OBJSLO = .lo/.c .lo/.cc .lo/.cxx .lo/.S .lo/.lo
+
+#%.lo: %.c
+#      $(CC) -o $@ $(LCFLAGS) -c $<
+
+c_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+cc_o_COMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+S_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(ASFLAGS) -DOMK_FOR_USER
+
+idl_COMPILE = $(IDL_COMPILER)
+
+# Check GCC version for user build
+ifndef CC_MAJOR_VERSION
+CC_MAJOR_VERSION := $(shell $(CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(CC_MAJOR_VERSION),2)
+CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+
+# Syntax: $(call COMPILE_c_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_c_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  CC      $$@"
+       $(Q) if $$(c_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call COMPILE_cc_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_cc_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  CXX     $$@"
+       $(Q) if $$(cc_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call COMPILE_S_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_S_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  AS      $$@"
+       $(Q) if $$(S_o_COMPILE) -D__ASSEMBLY__ $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+NM ?= nm
+
+# Syntax: $(call CMETRIC_o_h_template,<object_file>,<target_header>)
+define CMETRIC_o_h_template
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CMETRIC $$@"
+       $(Q)if [ -n `dirname $$@` ] ; then \
+             if [ ! -e `dirname $$@` ] ; then \
+               mkdir -p `dirname $$@` ; fi ; fi
+       $(Q)echo >$$@.tmp '/* Automatically generated from $$< */'
+       $(Q)echo >>$$@.tmp '/* Conditionals to control compilation */'
+# Bellow, the tricks with redirection are for shells without set -o pipefail
+# (see http://www.mail-archive.com/dash@vger.kernel.org/msg00149.html)
+       $(Q)exec 3>&1; status=`exec 4>&1 >&3; { $(NM) $$<; echo $$$$? >&4; }\
+               | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2cond_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+               | sort >>$$@.tmp` && exit $$$$status
+       $(Q)echo >>$$@.tmp '/* Defines from the values defined to symbols in hexadecimal format */'
+       $(Q)exec 3>&1; status=`exec 4>&1 >&3; { $(NM) $$<; echo $$$$? >&4; }\
+               | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2def_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+               | sort >>$$@.tmp` && exit $$$$status
+       $(Q)echo >>$$@.tmp '/* Defines from the values defined to symbols in decimal format */'
+       $(Q)exec 3>&1; status=`exec 4>&1 >&3; { $(NM) -td $$<; echo $$$$? >&4; }\
+               | sed -n 's/^ *0*\(0\|[1-9][0-9]*\) *A *_cmetric2defdec_\([A-Za-z_0-9]*\) */#define \2 \1/p' \
+               | sort >>$$@.tmp` && exit $$$$status
+       $(Q)mv $$@.tmp $$@
+endef
+
+
+
+define COMPILE_idl_template
+$(2).c $(2)-stubs.c $(2)-skels.c $(2)-common.c $(2).h: $(1) $$(wildcard $$(firstword $$(idl_COMPILE)))
+       @$(QUIET_CMD_ECHO) "  IDL     $$@"
+       $(Q) $$(idl_COMPILE) $$($(2)_IDLFLAGS) $(1)
+endef
+
+
+# Syntax: $(call PROGRAM_template,<dir>,<executable-name>,<executable-suffix>,<linker-sript>)
+# FIXME: ???????? asi je tu blbej komentar
+define PROGRAM_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS  += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(2)/$(1)$(3): $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  LINK    $$@"
+       $(Q) $$(if $$(filter %.cc,$$($(1)_SOURCES:%.cxx=%.cc)),$$(CXX),$$(CC)) \
+         $$($(1)_OBJS) $$($(1)_LIBS:%=-l%) $$(LOADLIBES) $$(LDFLAGS) $$($(1)_LDFLAGS) -Wl,-rpath-link,$(USER_LIB_DIR) -Wl,-Map,$(USER_OBJS_DIR)/$(1).exe.map -o $$@
+       @echo "$(2)/$(1)$(3): \\" >$(USER_OBJS_DIR)/$(1).exe.d
+       @sed -n -e 's|^LOAD \(.*\)$$$$|  \1  \&|p' $(USER_OBJS_DIR)/$(1).exe.map|tr '&' '\134'  >>$(USER_OBJS_DIR)/$(1).exe.d
+       @echo >>$(USER_OBJS_DIR)/$(1).exe.d
+endef
+
+
+# Syntax: $(call LIBRARY_template,<library-name>)
+define LIBRARY_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS  += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(USER_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  AR      $$@"
+       $(Q) $(AR) rcs $$@ $$^
+endef
+
+.PHONY: FORCE
+
+# Syntax: $(call SOLIB_template,<library-name>)
+define SOLIB_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+SOLIB_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJSLO),
+$(1)_OBJSLO += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJSLO := $$(sort $$($(1)_OBJSLO:%/=%))
+
+SOLIB_OBJS  += $$($(1)_OBJSLO)
+SOLIB_SOURCES += $$($(1)_SOURCES)
+
+$(OMK_WORK_DIR)/lib$(1).$(SOLIB_EXT).omkvar: $$($(1)_OBJSLO) FORCE
+       $(Q)echo '$(1)_objslo += $$$$(addprefix $(USER_OBJS_DIR)/,$$($(1)_OBJSLO))' > $$@.tmp; \
+           echo '$(1)_libs += $$($(1)_LIBS) $$(lib_LOADLIBES)' >> $$@.tmp; \
+           echo '$(1)_ldflags += $$($(1)_LDFLAGS) $$(lib_LDFLAGS)' >> $$@.tmp; \
+           echo 'shared_libs := $$$$(sort $(1) $$$$(shared_libs))' >> $$@.tmp; \
+           if cmp -s $$@.tmp $$@; then rm $$@.tmp; else mv $$@.tmp $$@; fi
+endef
+
+library-pass-local: $(addprefix $(USER_INCLUDE_DIR)/,$(cmetric_include_HEADERS)) \
+                   $(lib_LIBRARIES:%=$(USER_LIB_DIR)/lib%.a) $(shared_LIBRARIES:%=$(OMK_WORK_DIR)/lib%.$(SOLIB_EXT).omkvar)
+
+binary-pass-local: $(bin_PROGRAMS:%=$(USER_BIN_DIR)/%$(EXE_SUFFIX)) $(utils_PROGRAMS:%=$(USER_UTILS_DIR)/%$(EXE_SUFFIX)) $(test_PROGRAMS:%=$(USER_TESTS_DIR)/%$(EXE_SUFFIX))
+
+# Special rules for CMETRIC generated headers
+
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call COMPILE_c_o_template,\
+               $(SOURCES_DIR)/$($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES),\
+               $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),)))
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call CMETRIC_o_h_template,\
+               $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),\
+               $(addprefix $(USER_INCLUDE_DIR)/,$(cmetrh)))))
+
+GEN_HEADERS+=$(cmetric_include_HEADERS:%=$(USER_INCLUDE_DIR)/%)
+
+GEN_HEADERS+=$(filter %.h,$(USER_IDLS:%.idl=%.h))
+
+# Generate rules for compilation of programs and libraries
+
+$(foreach prog,$(utils_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_UTILS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(test_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_TESTS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(bin_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_BIN_DIR),$(EXE_SUFFIX))))
+
+$(foreach lib,$(lib_LIBRARIES),$(eval $(call LIBRARY_template,$(lib))))
+
+$(foreach lib,$(shared_LIBRARIES),$(eval $(call SOLIB_template,$(lib))))
+
+-include $(USER_OBJS_DIR)/*.d
+#FIXME: This doesn't include dependencies of source files from
+#subdirectories (i.s. *_SOURCES=dir/file.c. I'm currently not sure,
+#how to handle this.
+
+endif # USER_RULE_TEMPLATES
+
+.PHONY: link-pseudo-pass
+link-pseudo-pass:
+       $(Q)$(MAKE) $(NO_PRINT_DIRECTORY) -C $(USER_BUILD_DIR) -f $(SOURCESDIR_MAKEFILE) link-shared-libs
+
+ifeq ($(MAKECMDGOALS),link-shared-libs)
+
+# Syntax: $(call solib_link_template,<library-name>)
+define solib_link_template
+$(1)_shared_libs = $$(patsubst %,$(USER_LIB_DIR)/lib%.$(SOLIB_EXT),$$(filter $$(shared_libs),$$($(1)_libs)))
+#$$(warning $(1)_shared_libs = $$($(1)_shared_libs))
+$(USER_LIB_DIR)/lib$(1).$(SOLIB_EXT): $$($(1)_shared_libs) $$($(1)_objslo)
+       @$(QUIET_CMD_ECHO) "  LINK    $$@"
+       $(Q)$(CC) --shared -Xlinker -soname=lib$(1).$(SOLIB_EXT) -Wl,-Map,$(USER_OBJS_DIR)/lib$(1).$(SOLIB_EXT).map -o $$@ $$($(1)_objslo) $$(LOADLIBES) $$($(1)_libs:%=-l%) $$(lib_ldflags) $$($(1)_ldflags)
+endef
+
+-include $(shell true; find $(USER_BUILD_DIR) -name 'lib*.omkvar') # `true' is a hack for MinGW
+#$(warning $(shared_libs))
+$(foreach lib,$(shared_libs),$(eval $(call solib_link_template,$(lib))))
+
+.PHONY: link-shared-libs
+link-shared-libs: $(shared_libs:%=$(USER_LIB_DIR)/lib%.$(SOLIB_EXT))
+endif # link-shared-libs
+
+#=====================================================================
+# Kernel-space rules and templates to compile modules, libraries etc.
+
+ifdef KERN_RULE_TEMPLATES
+
+$(KERN_LIB_DIR)/kernel.mk: $(LINUX_DIR)/.config $(MAKERULES_DIR)/kernelcfg2mk
+       @$(QUIET_CMD_ECHO) "  KCFG2MK $@"
+       $(Q) $(MAKERULES_DIR)/kernelcfg2mk $(LINUX_DIR) $(KERN_LIB_DIR)
+
+ifeq ($(CONFIG_RTLINUX),y)
+include $(RTL_DIR)/rtl.mk
+
+KERN_CC = $(CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+INCLUDES := -I $(KERN_INCLUDE_DIR) $(INCLUDE) $(rtlinux_INCLUDES) $(kernel_INCLUDES)
+#-DEXPORT_NO_SYMBOLS
+c_o_kern_COMPILE = $(KERN_CC) -idirafter $(kern_GCCLIB_DIR)/include $(INCLUDES)  $(CFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(CXX) $(INCLUDES) $(CXXFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := .o
+KERN_ARCH = $(ARCH)
+KERN_LD = $(LD)
+KERN_AR = $(AR)
+
+else # CONFIG_RTLINUX
+
+include $(KERN_LIB_DIR)/kernel.mk
+
+ifeq ($(LINUX_SRC),)
+LINUX_SRC = $(LINUX_DIR)
+endif
+kernel_INCLUDES += -I $(KERN_INCLUDE_DIR) -I $(LINUX_DIR) -idirafter $(LINUX_SRC)/include/linux
+
+ifdef LINUX_CC
+KERN_CC = $(LINUX_CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(LINUX_CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+else
+KERN_CC = echo KERN_CC not defined - compilation skipped
+endif
+c_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+S_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_AFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+KERN_EXE_SUFFIX := $(LINUX_MODULE_EXT)
+KERN_LDFLAGS = $(LINUX_LDFLAGS)
+ifdef LINUX_ARCH
+KERN_ARCH = $(LINUX_ARCH)
+else
+KERN_ARCH = echo KERN_ARCH not defined - skipped
+endif
+ifdef LINUX_LD
+KERN_LD = $(LINUX_LD)
+else
+KERN_LD = echo KERN_LD  not defined - skipped
+endif
+ifneq ($(LINUX_AR),)
+KERN_AR = $(LINUX_AR)
+else
+KERN_AR = $(AR)
+endif
+ifeq ($(LINUX_QUOTE_MODNAME),y)
+KERN_MQ=\"
+KERN_KBUILD_MODNAME=-D"KBUILD_MODNAME=((THIS_MODULE)!=NULL?(THIS_MODULE)->name:NULL)"
+endif
+endif # CONFIG_RTLINUX
+
+KERN_LOADLIBES += -L$(KERN_LIB_DIR) 
+
+KERN_LOADLIBES += $(rtlinux_LOADLIBES:%=-l%)
+KERN_LOADLIBES += $(kernel_LOADLIBES:%=-l%)
+
+
+
+# Check GCC version for kernel part of build
+ifndef kern_CC_MAJOR_VERSION
+kern_CC_MAJOR_VERSION := $(shell $(KERN_CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(kern_CC_MAJOR_VERSION),2)
+kern_CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+kern_CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+ifeq ($(KERN_EXE_SUFFIX),.ko)
+ifeq ($(wildcard $(LINUX_DIR)/scripts/mod/modpost),)
+KERN_MODPOST = $(LINUX_DIR)/scripts/modpost
+else
+KERN_MODPOST = $(LINUX_DIR)/scripts/mod/modpost
+endif
+KERN_MODULES_LINK_DIR = $(KERN_MODPOST_DIR)
+KERN_LINK_SUFFIX = .o
+else
+KERN_MODULES_LINK_DIR = $(KERN_MODULES_DIR)
+KERN_LINK_SUFFIX = $(KERN_EXE_SUFFIX)
+endif
+
+ifeq ($(LINUX_CONFIG_MODVERSIONS),y)
+MODPOST_OPTS += -m
+MODPOST_OPTS += -i $(LINUX_DIR)/Module.symvers
+ifneq ($(LINUX_BUILDHOST),) # this is not correct point, it should look for 2.6.17 kernel
+MODPOST_OPTS += -I $(KERN_LIB_DIR)/Module.symvers
+endif
+MODPOST_OPTS += -o $(KERN_LIB_DIR)/Module.symvers
+endif
+
+ifeq ($(LINUX_CONFIG_DEBUG_SECTION_MISMATCH),y)
+MODPOST_OPTS += -S
+endif
+
+ifeq ($(LINUX_CONFIG_MARKERS),y)
+MODPOST_OPTS += -K $(LINUX_DIR)/Module.markers
+MODPOST_OPTS += -M $(KERN_LIB_DIR)/Module.markers
+endif
+
+ifeq ($(LINUX_KBUILD_MODPOST_WARN),y)
+MODPOST_OPTS += -w
+endif
+
+ifneq ($(LINUX_BUILDHOST),)
+ifneq ($(LINUX_BUILDHOST),$(LINUX_ARCH))
+MODPOST_OPTS += -c
+endif
+endif
+
+define COMPILE_c_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CC [K]  $$@"
+       $(Q) if $$(c_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define COMPILE_cc_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CXX [K] $$@"
+       $(Q) if $$(cc_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define COMPILE_S_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  AS [K]  $$@"
+       $(Q) if $$(S_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define MODULE_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS  += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+# this is hack to build "__this_module" structure for 2.6.x kernels
+# modpost is used for that purpose now
+
+#$(1).mod.c:
+#      echo  "\
+#      #include <linux/version.h>@\
+#      #include <linux/module.h>@\
+#      #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,5))@\
+#      #include <linux/vermagic.h>@\
+#      #include <linux/compiler.h>@\
+#      @\
+#      MODULE_INFO(vermagic, VERMAGIC_STRING);@\
+#      @\
+#      #undef unix@\
+#      struct module __this_module@\
+#      __attribute__((section(\".gnu.linkonce.this_module\"))) = {@\
+#       .name = __stringify(KBUILD_MODNAME),@\
+#       .init = init_module,@\
+#      #ifdef CONFIG_MODULE_UNLOAD@\
+#       .exit = cleanup_module,@\
+#      #endif@\
+#      };@\
+#      #endif@\
+#      " | tr @ \\n >$$@ 
+
+
+#$(eval $(call COMPILE_c_o_kern_template,$(1).mod.c,$(1).mod.o,-DKBUILD_MODNAME=$(1)))
+
+$(2)/$(1)$(KERN_LINK_SUFFIX): $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  LD [K]  $$@"
+       $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) -r $$($(1)_OBJS) -L$$(kern_GCCLIB_DIR) $$($(1)_LIBS:%=-l%) $$(KERN_LOADLIBES) -Map $(KERN_OBJS_DIR)/$(1).mod.map -o $$@
+       @echo "$(2)/$(1)$(KERN_LINK_SUFFIX): \\" >$(KERN_OBJS_DIR)/$(1).mod.d
+       @sed -n -e 's/^LOAD \(.*\)$$$$/  \1  \\/p' $(KERN_OBJS_DIR)/$(1).mod.map  >>$(KERN_OBJS_DIR)/$(1).mod.d
+       @echo >>$(KERN_OBJS_DIR)/$(1).mod.d
+       @if [ "$(KERN_EXE_SUFFIX)" = ".ko" ] ; then \
+         echo $(1) >>$(KERN_MODPOST_DIR)/module-changes ; \
+         echo $(1) >$(KERN_MODPOST_DIR)/$(1).mod.stamp ; \
+       fi
+
+endef
+
+
+
+define LIBRARY_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS  += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+$(KERN_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  AR [K]  $$@"
+       $(Q) $(KERN_AR) rcs $$@ $$^
+endef
+
+
+ifdef LINUX_DIR
+
+kernel-lib-pass-local: $(kernel_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+kernel-mod-pass-local: $(kernel_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+$(foreach module,$(kernel_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(kernel_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+
+ifeq ($(CONFIG_RTLINUX),y)
+
+kernel-mod-pass-local: $(rtlinux_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+kernel-lib-pass-local: $(rtlinux_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+$(foreach module,$(rtlinux_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(rtlinux_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+ifeq ($(KERN_MODPOST_PASS),y)
+
+MODULES_LIST :=        $(wildcard *.mod.stamp)
+MODULES_LIST := $(MODULES_LIST:%.mod.stamp=%)
+
+define MODPOST_kern_template
+$(2) : $(1)$(KERN_LINK_SUFFIX) $(1).mod.c
+       @$(QUIET_CMD_ECHO) "  LD [M]  $$@"
+       $(Q) $$(c_o_kern_COMPILE) -D"KBUILD_BASENAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+               -D"KBUILD_MODNAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+               -o $(1).mod.o -c $(1).mod.c
+       $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) $(1)$(KERN_LINK_SUFFIX) $(1).mod.o -r -o $$@
+endef
+
+kernel-modpost-versions: $(wildcard $(LINUX_DIR)/Module.symvers)
+       @$(QUIET_CMD_ECHO) "  MODPOST    $(KERN_MODPOST_DIR)"
+       @echo  >$(KERN_MODPOST_DIR)/modpost-running
+       @rm -f $(KERN_MODPOST_DIR)/module-changes
+       $(Q) $(KERN_MODPOST) $(MODPOST_OPTS) $(MODULES_LIST:%=%$(KERN_LINK_SUFFIX))
+
+$(MODULES_LIST:%=%.mod.c) : kernel-modpost-versions
+
+kernel-modpost-pass-local: $(MODULES_LIST:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX))
+       @rm -f $(KERN_MODPOST_DIR)/modpost-running
+
+$(foreach module,$(MODULES_LIST),$(eval $(call MODPOST_kern_template,$(module),$(module:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX)))))
+
+endif
+
+-include $(KERN_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+
+# Kernel requires its own set of configuration header-files
+ifneq ($(kernel_LIBRARIES)$(rtlinux_LIBRARIES)$(kernel_MODULES)$(rtlinux_MODULES)$(kernel_HEADERS)$(rtlinux_HEADERS)$(kernel_HEADERS)$(rtlinux_HEADERS)$(nobase_kernel_HEADERS)$(nobase_rtlinux_HEADERS)$(renamed_kernel_HEADERS)$(renamed_rtlinux_HEADERS),)
+KERN_CONFIG_HEADERS_REQUIRED = y
+endif
+
+$(eval $(call omk_pass_template, kernel-lib-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_LIBRARIES)$(rtlinux_LIBRARIES)))
+$(eval $(call omk_pass_template, kernel-mod-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_MODULES)$(rtlinux_MODULES)))
+
+kernel-modpost-pass:
+       +@if [ -e "$(KERN_MODPOST_DIR)/module-changes" -o -e "$(KERN_MODPOST_DIR)/modpost-running" ] ; \
+       then \
+           $(MAKE) --no-print-directory -C $(KERN_MODPOST_DIR) \
+              -f $(SOURCES_DIR)/Makefile KERN_RULE_TEMPLATES=y KERN_MODPOST_PASS=y $(@:%=%-local) ; \
+       fi
+
+$(eval $(call omk_pass_template, library-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(lib_LIBRARIES)$(shared_LIBRARIES)))
+$(eval $(call omk_pass_template, binary-pass, $(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(bin_PROGRAMS)$(utils_PROGRAMS)$(test_PROGRAMS)))
+
+$(eval $(call omk_pass_template,clean,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,install,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,include-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,always))
+
+check-dir::
+       @$(call mkdir_def,$(USER_BUILD_DIR))
+       @$(call mkdir_def,$(KERN_BUILD_DIR))
+       @$(call mkdir_def,$(USER_INCLUDE_DIR))
+       @$(call mkdir_def,$(KERN_INCLUDE_DIR))
+       @$(call mkdir_def,$(USER_LIB_DIR))
+       @$(call mkdir_def,$(KERN_LIB_DIR))
+       @$(call mkdir_def,$(USER_BIN_DIR))
+       @$(call mkdir_def,$(USER_UTILS_DIR))
+       @$(call mkdir_def,$(USER_TESTS_DIR))
+       @$(call mkdir_def,$(KERN_MODULES_DIR))
+       @$(call mkdir_def,$(KERN_MODPOST_DIR))
+
+install-local:                 # TODO
+
+$(eval $(call include-pass-template,$(USER_INCLUDE_DIR),include))
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),kernel))
+ifeq ($(CONFIG_RTLINUX),y)
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),rtlinux))
+endif
+
+
+ifdef USER_RULE_TEMPLATES
+
+# User-space static libraries and applications object files
+
+USER_SOURCES := $(sort $(USER_SOURCES))
+
+USER_GEN_SOURCES := $(sort $(USER_GEN_SOURCES))
+
+#$(warning USER_SOURCES = $(USER_SOURCES))
+
+$(foreach src,$(filter %.c,$(USER_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+
+$(foreach src,$(filter %.c,$(USER_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.o),)))
+
+# User-space shared libraries object files
+
+SOLIB_SOURCES := $(sort $(SOLIB_SOURCES))
+
+SOLIB_GEN_SOURCES := $(sort $(SOLIB_GEN_SOURCES))
+
+#$(warning SOLIB_SOURCES = $(SOLIB_SOURCES))
+#$(warning SOLIB_GEN_SOURCES = $(SOLIB_GEN_SOURCES))
+
+$(foreach src,$(filter %.c,$(SOLIB_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cc,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cxx,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.S,$(SOLIB_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.c,$(SOLIB_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+# Create _build directories for sources in subdirectories i.e. *_SOURCES=dir/file.c
+_dirs_to_create=$(filter-out ./,$(sort $(dir $(USER_SOURCES) $(SOLIB_SOURCES))))
+ifneq ($(_dirs_to_create),)
+$(shell mkdir -p $(addprefix $(LOCAL_BUILD_DIR)/,$(_dirs_to_create)))
+endif
+
+# IDL compilation
+
+USER_IDLS := $(sort $(USER_IDLS))
+
+$(foreach src,$(filter %.idl,$(USER_IDLS)),$(eval $(call COMPILE_idl_template,$(SOURCES_DIR)/$(src),$(src:%.idl=%))))
+
+endif
+
+ifdef KERN_RULE_TEMPLATES
+
+KERN_SOURCES := $(sort $(KERN_SOURCES))
+
+#$(warning KERN_SOURCES = $(KERN_SOURCES))
+
+$(foreach src,$(filter %.c,$(KERN_SOURCES)),$(eval $(call COMPILE_c_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+endif
+
+clean-local: clean-custom
+       @echo Cleaning in $(KERN_OBJS_DIR) and $(USER_OBJS_DIR)
+       @rm -f $(KERN_OBJS_DIR)/*.o $(USER_OBJS_DIR)/*.[och] $(USER_OBJS_DIR)/*.lo\
+              $(KERN_OBJS_DIR)/*.d $(USER_OBJS_DIR)/*.d \
+              $(KERN_OBJS_DIR)/*.map $(USER_OBJS_DIR)/*.map \
+              $(KERN_OBJS_DIR)/*.mod.c \
+              $(kernel_MODULES:%=$(KERN_MODPOST_DIR)/%.*) \
+              $(LOCAL_CONFIG_H:%=$(KERN_OBJS_DIR)/%) \
+              $(LOCAL_CONFIG_H:%=$(USER_OBJS_DIR)/%)
+       @if [ -e $(KERN_LIB_DIR)/kernel.mk ] ; then \
+           touch -t 200001010101 $(KERN_LIB_DIR)/kernel.mk ; \
+       fi
+
+include-pass-submakes: extra-rules-subdirs
+
+# We must go to EXTRA_RULES_SUBDIRS before going to any other
+# directory, since the executables compiled in EXTRA_RULES_SUBDIRS
+# might be needed there.
+include-pass-this-dir $(foreach subdir,$(SUBDIRS),include-pass-$(subdir)-subdir): extra-rules-subdirs
+
+default: include-pass library-pass binary-pass
+ifndef OMIT_KERNEL_PASSES
+# Also make kernel passes if not disabled
+default: kernel-lib-pass kernel-pass
+endif
+                                                                                 #OMK:config_h.omk@Makefile.rules.linux
+# Syntax: $(call BUILD_CONFIG_H_template,<stamp_dir>,<header_file_path>,<list_of_options_to_export>,<header_barrier>)
+define BUILD_CONFIG_H_template
+
+$(addprefix $(1)/,$(notdir $(addsuffix .stamp,$(2)))) : $(CONFIG_FILES)
+       @$(QUIET_CMD_ECHO) "  CONFGEN $(notdir $(2))"
+       @if [ ! -d `dirname $(2).tmp` ] ; then \
+               mkdir -p `dirname $(2).tmp` ; fi
+       @echo "/* Automatically generated from */" > "$(2).tmp"
+       @echo "/* config files: $$(^:$(OUTPUT_DIR)/%=%) */" >> "$(2).tmp"
+       $(if $(DOXYGEN),@echo "/** @file */" >> "$(2).tmp")
+       @echo "#ifndef $(4)" >> "$(2).tmp"
+       @echo "#define $(4)" >> "$(2).tmp"
+       @( $(foreach x, $(shell echo '$($(3))' | tr 'x\t ' 'x\n\n' | sed -e 's/^\([^ =]*\)\(=[^ ]\+\|\)$$/\1/' ), \
+               echo '$(x).$($(x))' ; ) echo ; ) | \
+               sed -e '/^[^.]*\.n$$$$/d' -e '/^[^.]*\.$$$$/d' -e 's/^\([^.]*\)\.[ym]$$$$/\1.1/' | \
+               sed -n -e 's/^\([^.]*\)\.\(.*\)$$$$/#define \1 \2/p' \
+                 >> "$(2).tmp"
+       @echo "#endif /*$(4)*/" >> "$(2).tmp"
+       @touch "$$@"
+       @if cmp --quiet "$(2).tmp" "$(2)" ; then rm "$(2).tmp"; \
+       else mv "$(2).tmp" "$(2)" ; \
+       echo "Updated configuration $(2)" ; fi
+
+endef
+
+ifdef LOCAL_CONFIG_H
+
+# This must be declared after the default cflags are assigned!
+# Override is used to override command line assignemnt.
+override CFLAGS += -I $(USER_OBJS_DIR)
+override kernel_INCLUDES += -I $(KERN_OBJS_DIR)
+$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(USER_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+
+endif
+
+# Special rules for configuration exported headers
+
+#FIXME: The directory for headers should not be specified here.
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(addprefix $(USER_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+config_h_stamp_files = $(addprefix $(USER_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(config_h_stamp_files)
+
+ifneq ($(KERN_CONFIG_HEADERS_REQUIRED),)
+
+ifdef LOCAL_CONFIG_H
+$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(KERN_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+endif
+
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(addprefix $(KERN_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+kern_config_h_stamp_files = $(addprefix $(KERN_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(kern_config_h_stamp_files)
+
+endif
+
+clean-local: clean-local-config-h
+
+clean-local-config-h:
+       @$(foreach confh,$(config_h_stamp_files) $(kern_config_h_stamp_files),\
+           if [ -e $(confh) ] ; then rm $(confh) ; fi ; \
+       )
+                                                                                 #OMK:qt.omk@Makefile.rules.linux
+ifneq ($(QT_SUBDIRS)$(QT_PROJECTS),)
+
+# Usage: $(call qt_project_template,<.pro_file relative to SOURCES_DIR>)
+define qt_project_template
+
+.PHONY: qt-subpass-$(1) clean-qt-$(dir $(1))
+
+# FIXME: Handle multiple .pro files correctly
+$(LOCAL_BUILD_DIR)/$(dir $(1))Makefile: $(SOURCES_DIR)/$(1)
+       $(Q)mkdir -p $$(dir $$(@)) && cd $$(dir $$(@)) &&               \
+       $(if $(QMAKE),$(QMAKE),$(QTDIR:%=%/bin/)qmake)                  \
+            TOP_DIR=$(OUTPUT_DIR)                                      \
+            RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir $(1))                 \
+            $(QTDIR:%=QTDIR=%) CC=$(CC) CXX=$(CXX)                     \
+            LIBS+="-L$(USER_LIB_DIR)" DESTDIR=$(USER_BIN_DIR)          \
+            INCLUDEPATH+="$(USER_INCLUDE_DIR)"                         \
+            QMAKE_LFLAGS="-Wl,-rpath-link,$(USER_LIB_DIR) $$(QMAKE_LFLAGS)" \
+            $(SOURCES_DIR)/$(1)
+
+# This horrible substitution is here to properly escape
+# -Wl,-rpath,$ORIGIN flags. It includes escaping for make, shell,
+# qmake and again make and shell run on qmake generated makefile.
+QMAKE_LFLAGS = $$(subst $$$$,\\\\\\$$$$\$$$$,$$(LDFLAGS))
+
+# Hook to binary pass
+binary-pass-submakes: qt-subpass-$(1)
+qt-subpass-$(1): $(LOCAL_BUILD_DIR)/$(dir $(1))Makefile
+       $(Q)$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir $(1)) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir $(1)) -C $(LOCAL_BUILD_DIR)/$(dir $(1)) || exit 1 ;
+
+# Hook to clean pass
+clean-local: clean-qt-$(dir $(1))
+clean-qt-$(dir $(1)): $(LOCAL_BUILD_DIR)/$(dir $(1))Makefile
+       @$(QUIET_CMD_ECHO) "  QT CLEAN $(dir $(1))"
+       $(Q)$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir $(1)) \
+         RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir $(1)) \
+         -C $(LOCAL_BUILD_DIR)/$(dir $(1)) clean
+       $(Q)rm $(LOCAL_BUILD_DIR)/$(dir $(1))Makefile
+endef
+
+$(foreach pro,$(QT_PROJECTS), $(eval $(call qt_project_template,$(pro))))
+$(foreach pro,$(foreach dir,$(QT_SUBDIRS), $(wildcard $(dir)/*.pro)), $(eval $(call qt_project_template,$(pro))))
+
+endif
+                                                                                 #OMK:sources-list.omk@Makefile.rules.linux
+# Rules that creates the list of files which are used during
+# compilation. The list reflects conditional compilation depending on
+# config.omk and other variables.
+
+SOURCES_LIST_FN=sources.txt
+ifndef SOURCES_LIST
+SOURCES_LIST_DIR:=$(RELATIVE_DIR)
+SOURCES_LIST:=$(OUTPUT_DIR)/$(SOURCES_LIST_DIR)/$(SOURCES_LIST_FN)
+SOURCES_LIST_D := $(LOCAL_BUILD_DIR)/$(SOURCES_LIST_FN).d
+export SOURCES_LIST SOURCES_LIST_DIR SOURCES_LIST_D
+endif
+
+ifneq ($(filter sources-list TAGS tags cscope,$(MAKECMDGOALS)),)
+NEED_SOURCES_LIST=y
+endif
+
+ifeq ($(NEED_SOURCES_LIST),y) # avoid execution of find command bellow if it is not useful
+.PHONY: sources-list
+sources-list: $(SOURCES_LIST)
+
+$(SOURCES_LIST): $(CONFIG_FILES) $(shell find -name $(MAKEFILE_OMK))
+       @$(call mkdir_def,$(dir $(SOURCES_LIST_D)))
+       @echo -n "" > "$(SOURCES_LIST).tmp"
+       @echo -n "" > "$(SOURCES_LIST_D).tmp"
+       @$(MAKE) --no-print-directory sources-list-pass
+       @echo "# Automatically generated list of files in '$(RELATIVE_DIR)' that are used during OMK compilation" > "$(SOURCES_LIST).tmp2"
+       @cat "$(SOURCES_LIST).tmp"|sort|uniq >> "$(SOURCES_LIST).tmp2"
+       @rm "$(SOURCES_LIST).tmp"
+       @mv "$(SOURCES_LIST).tmp2" "$(SOURCES_LIST)"
+       @echo "$(SOURCES_LIST): \\" > "$(SOURCES_LIST_D).tmp2"
+       @cat "$(SOURCES_LIST_D).tmp"|grep -v "$(SOURCES_LIST_D).tmp"|sort|uniq|\
+               sed -e 's/$$/\\/' >> "$(SOURCES_LIST_D).tmp2"
+       @rm "$(SOURCES_LIST_D).tmp"
+       @mv "$(SOURCES_LIST_D).tmp2" "$(SOURCES_LIST_D)"
+endif
+
+$(eval $(call omk_pass_template,sources-list-pass,$$(LOCAL_BUILD_DIR),,always))
+
+sources-list-pass-local:
+       @$(foreach m,$(MAKEFILE_LIST),echo '  $(m)' >> "$(SOURCES_LIST_D).tmp";)
+       @$(foreach h,$(include_HEADERS) $(nobase_include_HEADERS) $(kernel_HEADERS),\
+         echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(h)" >> "$(SOURCES_LIST).tmp";)
+       @$(foreach ch,$(config_include_HEADERS), \
+         echo "$(USER_INCLUDE_DIR:$(OUTPUT_DIR)/$(addsuffix /,$(SOURCES_LIST_DIR))%=%)/$(ch)" >> "$(SOURCES_LIST).tmp";)
+       @$(foreach h,$(renamed_include_HEADERS),echo '$(h)'|sed -e 's|\(.*\)->.*|$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))\1|' >> "$(SOURCES_LIST).tmp";)
+       @$(foreach bin,$(lib_LIBRARIES) $(shared_LIBRARIES) $(bin_PROGRAMS) $(test_PROGRAMS) $(utils_PROGRAMS) \
+         $(kernel_LIBRARIES) $(rtlinux_LIBRARIES) $(kernel_MODULES),\
+         $(foreach src,$(filter-out %.o,$($(bin)_SOURCES)),echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(src)" >> "$(SOURCES_LIST).tmp";))
+
+############ TAGS ###########
+
+ifeq ($(MAKECMDGOALS),TAGS)
+ETAGS=etags
+TAGS_CMD = $(ETAGS)
+TAGS: $(SOURCES_LIST)
+       @$(MAKE) --no-print-directory do-tags
+endif
+ifeq ($(MAKECMDGOALS),tags) 
+CTAGS=ctags -N
+TAGS_CMD = $(CTAGS)
+tags: $(SOURCES_LIST)
+       @$(MAKE) --no-print-directory do-tags
+endif
+export TAGS_CMD
+
+ifeq ($(MAKECMDGOALS),do-tags)
+.PHONY: do-tags
+do-tags: $(shell sed -e '/^\#/d' $(SOURCES_LIST))
+       @$(QUIET_CMD_ECHO) "  TAGS    $(SOURCES_LIST_FN)"
+       $(Q)$(TAGS_CMD) $^
+endif
+
+############ CSCOPE ###########
+
+cscope: $(SOURCES_LIST)
+       @$(QUIET_CMD_ECHO) "  CSCOPE  < $(SOURCES_LIST_FN)"
+       $(Q)sed -e '/^#/d' $(SOURCES_LIST) > cscope.files
+       $(Q)cscope -b -icscope.files
+#FIXME: see doc to -i in cscope(1)
diff --git a/build/aquosa/config.target b/build/aquosa/config.target
new file mode 100644 (file)
index 0000000..864d30e
--- /dev/null
@@ -0,0 +1,72 @@
+# -*- makefile -*-
+# Config file for compilation by OMK for AQuoSA/Linux OS target
+
+# You can override these variables in config.omk
+AQUOSA_ROOT ?= $(wildcard /usr/local/aquosa)
+QTDIR ?= $(wildcard /usr/share/qt4)
+
+test: wvtest
+.PHONY: test
+
+export PLATFORM=AQuoSA
+
+# Create symbolic links to headers instead of copying them. Useful
+# during development.
+LN_HEADERS=y
+
+# We do not want to overwrite original FRESCOR Makefiles
+USE_LEAF_MAKEFILES=n
+
+OMIT_KERNEL_PASSES=y
+
+########################################
+# Setting of compiler
+########################################
+
+# Instead, we call normal gcc with parameters which mgcc adds
+
+CFLAGS=$(ARCH_GCC_OPTS) -fpic -Wall -Wuninitialized -g -O1 -D_REENTRANT -D$(PLATFORM) -D_XOPEN_SOURCE=600 -D_BSD_SOURCE
+LDFLAGS=$(ARCH_LD_OPTS) $(LIBS_PATH) $(LIBS)
+LDFLAGS += '-Wl,-rpath,$$ORIGIN/../lib' -z origin --enable-new-dtags
+
+IDL_COMPILER = $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin/forb-idl
+
+# Other config
+FRSH_DISTRIBUTED_MODULE_SUPPORTED=true
+CONFIG_FORB_PROTO_UNIX=n
+CONFIG_FORB_PROTO_INET_DEFAULT=y
+
+# Disable tests which do not compile with FRSH_FORB
+
+CONFIG_FRSH_TEST_context_switch=n                            # Needs timespec_operations.h and frsh_os_compatibility.h
+CONFIG_FRSH_TEST_demo_september2007=n                        # Needs frsh_thread_get_vres_id()
+CONFIG_FRSH_TEST_demo_september2007_with_signals=n           # Some problem with signal constants and non-int vres_id
+CONFIG_FRSH_TEST_dl_test=n                                   # Needs different Makefile.omk
+CONFIG_FRSH_TEST_example_d-ac1_frescor=n                     # Needs int vres_id
+CONFIG_FRSH_TEST_frsh_shared_obj_test=n                      # Needs eat.h and timespec_operations.h
+CONFIG_FRSH_TEST_functions=n                                 # Needs timespec_operations.h and frsh_os_compatibility.h
+CONFIG_FRSH_TEST_jitter_test=n                                       # Needs timespec_operations.h and frsh_os_compatibility.h
+CONFIG_FRSH_TEST_sharedobj_prototype=n                               # Needs frsh_sharedobj_XXX
+CONFIG_FRSH_TEST_test_bind=n                                 # Needs eat.h and timespec_operations.h
+CONFIG_FRSH_TEST_test_contract_labels=n                      # Needs eat.h and timespec_operations.h
+CONFIG_FRSH_TEST_test_eat=n                                  # Needs eat.h
+CONFIG_FRSH_TEST_test_frsh_performance=n                     # Needs more frsh api - todo
+CONFIG_FRSH_TEST_test_frsh_renegotiate_async=n                       # Needs eat.h and timespec_operations.h
+CONFIG_FRSH_TEST_test_frsh_synch_obj=n                               # Needs frsh_thread_id_t to be simple type - Aquosa declares it as structure
+CONFIG_FRSH_TEST_test_memory=n                                       # Needs different Makefile.omk and then we will see :)
+CONFIG_FRSH_TEST_demo_sept07_negotiate_and_send=n            # Needs RTEP
+CONFIG_FRSH_TEST_demo_sept07_negotiations_limit=n            # Needs RTEP
+CONFIG_FRSH_TEST_demo_sept07_renegotiate_and_send=n          # Needs RTEP
+CONFIG_FRSH_TEST_test_endpoints=n                            # Needs RTEP
+CONFIG_FRSH_TEST_test_frsh_distributed_contract_negotiate=n   # Nedds vres_id to be int
+CONFIG_FRSH_TEST_test_frsh_distributed_contract_renegotiate=n # Needs RTEP
+CONFIG_FRSH_TEST_test_frsh_distributed_init=n                # Needs THE_FRSH_CPU_ID
+CONFIG_FRSH_TEST_test_frsh_marshal=n                         # Accesses frsh_contract_t fields directly
+CONFIG_FRSH_TEST_test_frsh_send_receive_basic=n              # Needs RTEP
+CONFIG_FRSH_TEST_test_get_network_info=n                     # Needs RTEP
+CONFIG_FRSH_TEST_test_self_bind=n                            # Needs eat.h and timespec_operations.h
+CONFIG_FRSH_TEST_test_sizes=n                                # Needs frsh_internal.h - TODO
+CONFIG_FRSH_TEST_test_spare_capacity=n                               # Needs more frsh api - TODO
+CONFIG_FRSH_TEST_test_timespec_operations=n                  # Needs timespec_operations.h
+CONFIG_FRSH_TEST_test_vres_id_bits=n                         # Depends on bit-fields in integer vres_id
+CONFIG_FSA_TESTS=n                                           # Depends on bit-fields in integer vres_id
diff --git a/build/aquosa/create-links b/build/aquosa/create-links
new file mode 100755 (executable)
index 0000000..b9fd523
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# Usage: ./create-links [path/to/frescor/root]
+#
+# path/to/frescor/root defaults to ../..
+
+LINKS="
+fna
+forb
+fosa
+frsh
+frsh_forb
+fwp/fwp
+ulut
+utils
+"
+
+FRESCOR_SRC=${1:-../..}
+
+for link in $LINKS; do
+       ln -s $FRESCOR_SRC/$link .
+done
+
diff --git a/build/aquosa/fna b/build/aquosa/fna
new file mode 120000 (symlink)
index 0000000..75492d5
--- /dev/null
@@ -0,0 +1 @@
+../../src/fna
\ No newline at end of file
diff --git a/build/aquosa/forb b/build/aquosa/forb
new file mode 120000 (symlink)
index 0000000..8aab5ae
--- /dev/null
@@ -0,0 +1 @@
+../../src/forb
\ No newline at end of file
diff --git a/build/aquosa/fosa b/build/aquosa/fosa
new file mode 120000 (symlink)
index 0000000..d63c04c
--- /dev/null
@@ -0,0 +1 @@
+../../src/fosa
\ No newline at end of file
diff --git a/build/aquosa/frsh b/build/aquosa/frsh
new file mode 120000 (symlink)
index 0000000..ade6dfd
--- /dev/null
@@ -0,0 +1 @@
+../../src/frsh
\ No newline at end of file
diff --git a/build/aquosa/frsh-forb-demo.sh b/build/aquosa/frsh-forb-demo.sh
new file mode 100755 (executable)
index 0000000..163b61c
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh -x
+
+[ -d _compiled/bin ] && PATH=_compiled/bin:$PATH
+
+fcb&
+FCB_PID=$!
+sleep 1
+frm_gui &
+GUI_PID=$!
+frm_dummy &
+DUMMY_PID=$!
+sleep 1
+dummy_spare_capacity &
+S1=$!
+dummy_renegotiation &
+R1=$!
+sleep 1
+dummy_renegotiation &
+R1=$!
+frm_fwp &
+FWP_PID=$!
+wait $GUI_PID
+kill $FWP_PID $DUMMY_PID $FCB_PID $R1 $R2 $S1
diff --git a/build/aquosa/frsh-include b/build/aquosa/frsh-include
new file mode 120000 (symlink)
index 0000000..087eb78
--- /dev/null
@@ -0,0 +1 @@
+../../src/frsh-include
\ No newline at end of file
diff --git a/build/aquosa/fwp b/build/aquosa/fwp
new file mode 120000 (symlink)
index 0000000..e12793f
--- /dev/null
@@ -0,0 +1 @@
+../../src/fwp/fwp
\ No newline at end of file
diff --git a/build/aquosa/kernelcfg2mk b/build/aquosa/kernelcfg2mk
new file mode 100755 (executable)
index 0000000..3fd50d2
--- /dev/null
@@ -0,0 +1,217 @@
+#!/bin/bash
+
+if [ $# -lt 1 ] ; then
+  echo "kernelcfg2mk: requires linux kernel directory as the first argument"
+  exit 2
+fi
+
+LINUX_DIR="$1"
+
+if [ $# -gt 1 ] ; then
+  KERN_MODULES_DIR="$2"
+fi
+
+if [ ! -e $LINUX_DIR/.config ] ; then
+  echo "kernelcfg2mk: the provided locations doesnot point to configured kernel sources"
+  echo "        check directory $LINUX_DIR"
+  exit 2
+fi
+
+if [ ! -e $LINUX_DIR/.config ] ; then
+  echo "kernelcfg2mk: the provided locations doesnot point to configured kernel sources"
+  echo "        check directory $LINUX_DIR"
+  exit 2
+fi
+
+if [ -z "$KERN_BUILD_DIR" ]  ; then
+  KERN_BUILD_DIR=`pwd`
+fi
+
+if [ -z "$KERN_MODULES_DIR" ]  ; then
+  KERN_MODULES_DIR=`pwd`
+fi
+
+
+if [ -z "$MAKE" ]  ; then
+  MAKE="make"
+fi
+
+
+KERN_TEST_DIR="$KERN_BUILD_DIR/kern-test-mk"
+
+mkdir -p $KERN_TEST_DIR
+
+#echo MAKERULES_DIR $MAKERULES_DIR
+#echo LINUX_DIR $LINUX_DIR
+#echo KERN_BUILD_DIR $KERN_BUILD_DIR
+#echo KERN_MODULES_DIR $KERN_MODULES_DIR
+
+RETVAL="0"
+
+LINUX_VERSION=$(grep UTS_RELEASE ${LINUX_DIR}/include/linux/version.h | \
+               sed 's/[^"]*"\(.*\)\{1\}"/\1/')
+if [ -z "$LINUX_VERSION" ] ; then
+  LINUX_VERSION=$(grep UTS_RELEASE ${LINUX_DIR}/include/linux/utsrelease.h | \
+                 sed 's/[^"]*"\(.*\)\{1\}"/\1/')
+fi
+if [ -z "$LINUX_VERSION" ] ; then
+  LINUX_VERSION=$(grep UTS_RELEASE ${LINUX_DIR}/include/generated/utsrelease.h | \
+                 sed 's/[^"]*"\(.*\)\{1\}"/\1/')
+fi
+
+LINUX_VERSION_MAJOR=$(echo ${LINUX_VERSION} | cut -d. -f1)
+LINUX_VERSION_MINOR=$(echo ${LINUX_VERSION} | cut -d. -f2)
+
+#echo $LINUX_VERSION
+#echo $LINUX_VERSION_MAJOR
+#echo $LINUX_VERSION_MINOR
+
+
+case $LINUX_VERSION_MAJOR.$LINUX_VERSION_MINOR in
+
+
+#=====================================================================
+# test for 2.4.x kernels
+    2.[01234])
+
+       rm -f ${KERN_BUILD_DIR}/kernel.mk
+       rm -rf ${KERN_TEST_DIR}
+       mkdir ${KERN_TEST_DIR}
+       if [ $? -ne 0 ] ; then
+               echo "Cannot create Linux kernel test build directory \"${KERN_TEST_DIR}\""
+               exit 3
+       fi
+       cd ${KERN_TEST_DIR}
+
+       cat >${KERN_TEST_DIR}/Makefile <<EOF
+
+.PHONY: modules
+modules:
+       @echo LINUX_ARCH="\$(ARCH)" >>flags
+       @echo LINUX_LDFLAGS="" >>flags
+       @echo LINUX_ARFLAGS="\$(ARFLAGS)" >>flags
+       @echo LINUX_CROSS_COMPILE="\$(CROSS_COMPILE)" >>flags
+       @echo LINUX_KERNELRELEASE="\$(KERNELRELEASE)" >>flags
+       @echo LINUX_AFLAGS="\$(AFLAGS)" | sed 's#Iinclude#I"\$(LINUXDIR)/include"#g'>>flags
+       @echo LINUX_CFLAGS="\$(CFLAGS)" | sed 's#Iinclude#I"\$(LINUXDIR)/include"#g'>>flags
+       @echo LINUX_MODFLAGS="\$(MODFLAGS)"
+       @echo LINUX_CC="\$(CC)" >>flags
+       @echo LINUX_LD="\$(LD) \$(LDFLAGS)" >>flags
+       @echo LINUX_AS="\$(AS)" >>flags
+       @echo LINUX_AR="\$(AR)" >>flags
+       @echo LINUX_MODULE_EXT=".o" >>flags
+
+EOF
+
+       #echo ${MAKE} -C ${LINUX_DIR} SUBDIRS=${KERN_TEST_DIR} modules
+       ${MAKE} -C ${LINUX_DIR} SUBDIRS=${KERN_TEST_DIR} modules
+       if [ $? == 0 ] ; then
+               cp -v flags ${KERN_MODULES_DIR}/kernel.mk       
+               if [ ! $? == 0 ] ; then
+                       RETVAL="2"
+               fi
+       else
+               RETVAL="1"
+       fi
+
+       cd ${KERN_BUILD_DIR}
+       rm -rf ${KERN_TEST_DIR}
+       ;;
+
+#=====================================================================
+# test for 2.6.x kernels
+
+    2.6)
+
+       rm -f ${KERN_BUILD_DIR}/kernel.mk
+       rm -rf ${KERN_TEST_DIR}
+       mkdir ${KERN_TEST_DIR}
+       if [ $? -ne 0 ] ; then
+               echo "Cannot create Linux kernel test build directory \"${KERN_TEST_DIR}\""
+               exit 3
+       fi
+       cd ${KERN_TEST_DIR}
+
+       cat >${KERN_TEST_DIR}/Makefile <<EOF
+obj-m += fake.o
+
+\$(obj)/fake.c: flags
+       touch \$(obj)/fake.c
+
+ifeq (\$(KBUILD_SRC),)
+OMK_LINUX_SRC = \$(LINUXDIR)
+else
+OMK_LINUX_SRC = \$(KBUILD_SRC)
+endif
+#\$(warning Test \$OMK_LINUX_SRC)
+
+.PHONY: flags
+flags:
+       @echo LINUX_SRC="\$(OMK_LINUX_SRC)" >>\$(obj)/flags
+       @echo LINUX_ARCH="\$(ARCH)" >>\$(obj)/flags
+       @echo LINUX_BUILDHOST="\$(KBUILD_BUILDHOST)" >>\$(obj)/flags
+       @echo LINUX_LDFLAGS="" >>\$(obj)/flags
+       @echo LINUX_ARFLAGS="\$(ARFLAGS)" >>\$(obj)/flags
+       @echo LINUX_CROSS_COMPILE="\$(CROSS_COMPILE)" >>\$(obj)/flags
+       @echo LINUX_KERNELRELEASE="\$(KERNELRELEASE)" >>\$(obj)/flags
+ifdef KBUILD_CFLAGS
+       @echo LINUX_CPPFLAGS="\$(KBUILD_CPPFLAGS)\$(if \$(filter -I,\$(KBUILD_CPPFLAGS)),, \$(LINUXINCLUDE))" | sed 's#-I\(include\|arch\)#-I"\$(LINUXDIR)/\1"#g'>>\$(obj)/flags
+       @echo LINUX_AFLAGS="\$(KBUILD_AFLAGS)" | sed 's#-I\(include\|arch\)#-I"\$(OMK_LINUX_SRC)/\1"#g'>>\$(obj)/flags
+       @echo LINUX_CFLAGS="\$(KBUILD_CFLAGS)" | sed 's#-I\(include\|arch\)#-I"\$(OMK_LINUX_SRC)/\1"#g'>>\$(obj)/flags
+else
+       @echo LINUX_CPPFLAGS="\$(CPPFLAGS)" | sed 's#Iinclude#I"\$(LINUXDIR)/include"#g'>>\$(obj)/flags
+       @echo LINUX_AFLAGS="\$(AFLAGS)" | sed 's#Iinclude#I"\$(OMK_LINUX_SRC)/include"#g'>>\$(obj)/flags
+       @echo LINUX_CFLAGS="\$(CFLAGS)" | sed 's#Iinclude#I"\$(OMK_LINUX_SRC)/include"#g'>>\$(obj)/flags
+endif
+       @echo LINUX_CFLAGS_MODULE="\$(CFLAGS_MODULE)" >>\$(obj)/flags
+       @echo LINUX_CC="\$(CC)" >>\$(obj)/flags
+       @echo LINUX_LD="\$(LD) \$(LDFLAGS) \$(LDFLAGS_MODULE)" | sed 's#\(\<arch/[^ ]*\.o\>\)#"\$(LINUXDIR)/\1"#g' >>\$(obj)/flags
+       @echo LINUX_AS="\$(AS)" >>\$(obj)/flags
+       @echo LINUX_AR="\$(AR)" >>\$(obj)/flags
+       @echo LINUX_MODULE_EXT=".ko" >>\$(obj)/flags
+       @echo LINUX_QUOTE_MODNAME=\$(if \$(findstring KBUILD_STR,\$(basename_flags)),y,) >>\$(obj)/flags
+       @echo LINUX_CONFIG_MODVERSIONS=\$(CONFIG_MODVERSIONS) >>\$(obj)/flags
+       @echo LINUX_CONFIG_MODULE_SRCVERSION_ALL=\$(CONFIG_MODULE_SRCVERSION_ALL) >>\$(obj)/flags
+       @echo LINUX_CONFIG_DEBUG_SECTION_MISMATCH=\$(CONFIG_DEBUG_SECTION_MISMATCH) >>\$(obj)/flags
+       @echo LINUX_CONFIG_MARKERS=\$(CONFIG_MARKERS) >>\$(obj)/flags
+       @echo LINUX_KBUILD_EXTMOD=\$(KBUILD_EXTMOD) >>\$(obj)/flags
+       @echo LINUX_KBUILD_EXTRA_SYMBOLS=\$(KBUILD_EXTRA_SYMBOLS) >>\$(obj)/flags
+       @echo LINUX_KBUILD_MODPOST_WARN=\$(KBUILD_MODPOST_WARN) >>\$(obj)/flags
+       @echo LINUX_CROSS_BUILD=\$(cross_build) >>\$(obj)/flags
+EOF
+
+       # modkern_cflags := $(CFLAGS_KERNEL) / $(CFLAGS_MODULE)
+
+       # _c_flags       = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o)
+       # _a_flags       = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o)
+       # _cpp_flags     = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F))
+
+       # export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
+       # export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
+       # export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
+
+       #  -p V=1
+       #echo ${MAKE} -C ${LINUX_DIR} SUBDIRS=${KERN_TEST_DIR} LINUXDIR=${LINUX_DIR} MODVERDIR=${KERN_TEST_DIR} modules
+       ${MAKE} -C ${LINUX_DIR} M=${KERN_TEST_DIR} LINUXDIR=${LINUX_DIR} MODVERDIR=${KERN_TEST_DIR}/modver modules
+       #if [ $? == 0 ] ; then
+               cp -v flags ${KERN_MODULES_DIR}/kernel.mk       
+               if [ ! $? == 0 ] ; then
+                       RETVAL="2"
+               fi
+       #else
+       #       RETVAL="1"
+       #fi
+
+       cd ${KERN_BUILD_DIR}
+       rm -rf ${KERN_TEST_DIR}
+       ;;
+
+#=====================================================================
+
+    *)
+       echo "Unsupported Linux version $LINUX_VERSION_MAJOR.$LINUX_VERSION_MINOR"
+    ;;
+esac
+
+
+exit ${RETVAL}
diff --git a/build/aquosa/ulut b/build/aquosa/ulut
new file mode 120000 (symlink)
index 0000000..77b914d
--- /dev/null
@@ -0,0 +1 @@
+../../src/ulut/ulut
\ No newline at end of file
diff --git a/build/aquosa/wvtest/c/Makefile.omk b/build/aquosa/wvtest/c/Makefile.omk
new file mode 100644 (file)
index 0000000..6614b78
--- /dev/null
@@ -0,0 +1,7 @@
+
+include_HEADERS = wvtest.h
+
+CFLAGS += -DWVTEST_CONFIGURED
+
+lib_LIBRARIES = wvtest
+wvtest_SOURCES = wvtestmain.c wvtest.c wvtestfrsh.c
diff --git a/build/aquosa/wvtest/c/wvtest.c b/build/aquosa/wvtest/c/wvtest.c
new file mode 100644 (file)
index 0000000..ecbfbf7
--- /dev/null
@@ -0,0 +1,394 @@
+/*
+ * WvTest:
+ *   Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ *       Licensed under the GNU Library General Public License, version 2.
+ *       See the included file named LICENSE for license information.
+ */
+#include "wvtest.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#ifdef _WIN32
+#include <direct.h>
+#else
+#include <unistd.h>
+#include <sys/wait.h>
+#endif
+#include <errno.h>
+#include <signal.h>
+
+#include <stdlib.h>
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+# include <valgrind/memcheck.h>
+# include <valgrind/valgrind.h>
+#else
+# define VALGRIND_COUNT_ERRORS 0
+# define VALGRIND_DO_LEAK_CHECK
+# define VALGRIND_COUNT_LEAKS(a,b,c,d) (a=b=c=d=0)
+#endif
+
+#define MAX_TEST_TIME 40     // max seconds for a single test to run
+#define MAX_TOTAL_TIME 120*60 // max seconds for the entire suite to run
+
+#define TEST_START_FORMAT "! %s:%-5d %-40s "
+
+static int fails, runs;
+static time_t start_time;
+static bool run_twice;
+    
+static void alarm_handler(int sig);
+   
+static int memerrs()
+{
+    return (int)VALGRIND_COUNT_ERRORS;
+}
+
+static int memleaks()
+{
+    int leaked = 0, dubious = 0, reachable = 0, suppressed = 0;
+    VALGRIND_DO_LEAK_CHECK;
+    VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed);
+    printf("memleaks: sure:%d dubious:%d reachable:%d suppress:%d\n",
+          leaked, dubious, reachable, suppressed);
+    fflush(stdout);
+    
+    // dubious+reachable are normally non-zero because of globals...
+    // return leaked+dubious+reachable;
+    return leaked;
+}
+
+// Return 1 if no children are running or zombies, 0 if there are any running
+// or zombie children.
+// Will wait for any already-terminated children first.
+// Passes if no rogue children were running, fails otherwise.
+// If your test gets a failure in here, either you're not killing all your
+// children, or you're not calling waitpid(2) on all of them.
+static bool no_running_children()
+{
+#ifndef _WIN32
+    pid_t wait_result;
+
+    // Acknowledge and complain about any zombie children
+    do 
+    {
+       int status = 0;
+        wait_result = waitpid(-1, &status, WNOHANG);
+
+        if (wait_result > 0)
+        {
+            char buf[256];
+            snprintf(buf, sizeof(buf) - 1, "%d", wait_result);
+            buf[sizeof(buf)-1] = '\0';
+            WVFAILEQ("Unclaimed dead child process", buf);
+        }
+    } while (wait_result > 0);
+        
+    // There should not be any running children, so waitpid should return -1
+    WVPASS(errno == ECHILD);
+    WVPASS(wait_result == -1);
+    return (wait_result == -1 && errno == ECHILD);
+#endif
+    return true;
+}
+
+
+static void alarm_handler(int sig)
+{
+    printf("\n! WvTest  Current test took longer than %d seconds!  FAILED\n",
+          MAX_TEST_TIME);
+    fflush(stdout);
+    abort();
+}
+
+
+static const char *pathstrip(const char *filename)
+{
+    const char *cptr;
+    cptr = strrchr(filename, '/');
+    if (cptr) filename = cptr + 1;
+    cptr = strrchr(filename, '\\');
+    if (cptr) filename = cptr + 1;
+    return filename;
+}
+
+static bool prefix_match(const char *s, char * const *prefixes)
+{
+    char *const *prefix;
+    for (prefix = prefixes; prefix && *prefix; prefix++)
+    {
+       if (!strncasecmp(s, *prefix, strlen(*prefix)))
+           return true;
+    }
+    return false;
+}
+
+extern struct WvTest *__start_wvtest, *__stop_wvtest;
+
+int wvtest_run_all(char * const *prefixes)
+{
+    int old_valgrind_errs = 0, new_valgrind_errs;
+    int old_valgrind_leaks = 0, new_valgrind_leaks;
+    
+#ifdef _WIN32
+    /* I should be doing something to do with SetTimer here, 
+     * not sure exactly what just yet */
+#else
+    char *disable = getenv("WVTEST_DISABLE_TIMEOUT");
+    if (disable != NULL && disable[0] != '\0' && disable[0] != '0')
+        signal(SIGALRM, SIG_IGN);
+    else
+        signal(SIGALRM, alarm_handler);
+    alarm(MAX_TEST_TIME);
+#endif
+    start_time = time(NULL);
+    
+    // make sure we can always start out in the same directory, so tests have
+    // access to their files.  If a test uses chdir(), we want to be able to
+    // reverse it.
+    char wd[1024];
+    if (!getcwd(wd, sizeof(wd)))
+       strcpy(wd, ".");
+    
+    const char *slowstr1 = getenv("WVTEST_MIN_SLOWNESS");
+    const char *slowstr2 = getenv("WVTEST_MAX_SLOWNESS");
+    int min_slowness = 0, max_slowness = 65535;
+    if (slowstr1) min_slowness = atoi(slowstr1);
+    if (slowstr2) max_slowness = atoi(slowstr2);
+
+#ifdef _WIN32
+    run_twice = false;
+#else
+    char *parallel_str = getenv("WVTEST_PARALLEL");
+    if (parallel_str) 
+        run_twice = atoi(parallel_str) > 0;
+#endif
+
+    // there are lots of fflush() calls in here because stupid win32 doesn't
+    // flush very often by itself.
+    fails = runs = 0;
+    struct WvTest *cur, **p;
+    for (p = &__start_wvtest; p < &__stop_wvtest; p++)
+    {
+       cur = *p;
+       if (cur->slowness <= max_slowness
+           && cur->slowness >= min_slowness
+           && (!prefixes
+               || prefix_match(cur->idstr, prefixes)
+               || prefix_match(cur->descr, prefixes)))
+       {
+#ifndef _WIN32
+            // set SIGPIPE back to default, helps catch tests which don't set
+            // this signal to SIG_IGN (which is almost always what you want)
+            // on startup
+            signal(SIGPIPE, SIG_DFL);
+
+            pid_t child = 0;
+            if (run_twice)
+            {
+                // I see everything twice!
+                printf("Running test in parallel.\n");
+                child = fork();
+            }
+#endif
+
+           printf("\nTesting \"%s\" in %s:\n", cur->descr, cur->idstr);
+           fflush(stdout);
+           
+           cur->main();
+           chdir(wd);
+           
+           new_valgrind_errs = memerrs();
+           WVPASS(new_valgrind_errs == old_valgrind_errs);
+           old_valgrind_errs = new_valgrind_errs;
+           
+           new_valgrind_leaks = memleaks();
+           WVPASS(new_valgrind_leaks == old_valgrind_leaks);
+           old_valgrind_leaks = new_valgrind_leaks;
+           
+           fflush(stderr);
+           printf("\n");
+           fflush(stdout);
+
+#ifndef _WIN32
+            if (run_twice)
+            {
+                if (!child)
+                {
+                    // I see everything once!
+                    printf("Child exiting.\n");
+                    _exit(0);
+                }
+                else
+                {
+                    printf("Waiting for child to exit.\n");
+                    int result;
+                    while ((result = waitpid(child, NULL, 0)) == -1 && 
+                            errno == EINTR)
+                        printf("Waitpid interrupted, retrying.\n");
+                }
+            }
+#endif
+
+            WVPASS(no_running_children());
+       }
+    }
+    
+    WVPASS(runs > 0);
+    
+    if (prefixes && *prefixes && **prefixes)
+       printf("WvTest: WARNING: only ran tests starting with "
+              "specifed prefix(es).\n");
+    else
+       printf("WvTest: ran all tests.\n");
+    printf("WvTest: %d test%s, %d failure%s.\n",
+          runs, runs==1 ? "" : "s",
+          fails, fails==1 ? "": "s");
+    fflush(stdout);
+    
+    return fails != 0;
+}
+
+
+// If we aren't running in parallel, we want to output the name of the test
+// before we run it, so we know what happened if it crashes.  If we are
+// running in parallel, outputting this information in multiple printf()s
+// can confuse parsers, so we want to output everything in one printf().
+//
+// This function gets called by both start() and check().  If we're not
+// running in parallel, just print the data.  If we're running in parallel,
+// and we're starting a test, save a copy of the file/line/description until
+// the test is done and we can output it all at once.
+//
+// Yes, this is probably the worst API of all time.
+static void print_result_str(bool start, const char *_file, int _line, 
+                            const char *_condstr, const char *result)
+{
+    static char *file;
+    static char *condstr;
+    static int line;
+    char *cptr;
+    
+    if (start)
+    {
+        if (file) 
+            free(file);
+        if (condstr) 
+            free(condstr);
+        file = strdup(pathstrip(_file));
+        condstr = strdup(_condstr);
+        line = _line;
+
+        for (cptr = condstr; *cptr; cptr++)
+        {
+            if (!isprint((unsigned char)*cptr))
+                *cptr = '!';
+        }
+    }
+            
+    if (run_twice)
+    {
+        if (!start)
+            printf(TEST_START_FORMAT "%s\n", file, line, condstr, result);
+    }
+    else
+    {
+        if (start)
+            printf(TEST_START_FORMAT, file, line, condstr);
+        else
+            printf("%s\n", result);
+    }
+    fflush(stdout);
+
+    if (!start)
+    {
+        if (file)
+            free(file);
+        if (condstr)
+            free(condstr);
+        file = condstr = NULL;
+    }
+}
+
+static inline void
+print_result(bool start, const char *file, int line, 
+            const char *condstr, bool result)
+{
+       print_result_str(start, file, line, condstr, result ? "ok" : "FAILED");
+}
+
+void wvtest_start(const char *file, int line, const char *condstr)
+{
+    // Either print the file, line, and condstr, or save them for later.
+    print_result(true, file, line, condstr, false);
+}
+
+
+void wvtest_check(bool cond, const char *reason)
+{
+#ifndef _WIN32
+    alarm(MAX_TEST_TIME); // restart per-test timeout
+#endif
+    if (!start_time) start_time = time(NULL);
+    
+    if (time(NULL) - start_time > MAX_TOTAL_TIME)
+    {
+       printf("\n! WvTest   Total run time exceeded %d seconds!  FAILED\n",
+              MAX_TOTAL_TIME);
+       fflush(stdout);
+       abort();
+    }
+    
+    runs++;
+
+    print_result_str(false, NULL, 0, NULL, cond ? "ok" : (reason ? reason : "FAILED"));
+
+    if (!cond)
+    {
+       fails++;
+       
+       if (getenv("WVTEST_DIE_FAST"))
+           abort();
+    }
+}
+
+
+bool wvtest_start_check_eq(const char *file, int line,
+                           const char *a, const char *b, bool expect_pass)
+{
+    if (!a) a = "";
+    if (!b) b = "";
+    
+    size_t len = strlen(a) + strlen(b) + 8 + 1;
+    char str[len];
+    sprintf(str, "[%s] %s [%s]", a, expect_pass ? "==" : "!=", b);
+    
+    wvtest_start(file, line, str);
+    
+    bool cond = !strcmp(a, b);
+    if (!expect_pass)
+        cond = !cond;
+
+    wvtest_check(cond, NULL);
+    return cond;
+}
+
+
+bool wvtest_start_check_lt(const char *file, int line,
+                           const char *a, const char *b)
+{
+    if (!a) a = "";
+    if (!b) b = "";
+    
+    size_t len = strlen(a) + strlen(b) + 8 + 1;
+    char *str = malloc(len);
+    sprintf(str, "[%s] < [%s]", a, b);
+    
+    wvtest_start(file, line, str);
+    free(str);
+
+    bool cond = strcmp(a, b) < 0;
+    wvtest_check(cond, NULL);
+    return cond;
+}
diff --git a/build/aquosa/wvtest/c/wvtest.h b/build/aquosa/wvtest/c/wvtest.h
new file mode 100644 (file)
index 0000000..79c8da6
--- /dev/null
@@ -0,0 +1,69 @@
+/* -*- Mode: C -*-
+ * WvTest:
+ *   Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ *       Licensed under the GNU Library General Public License, version 2.
+ *       See the included file named LICENSE for license information.
+ */ 
+#ifndef __WVTEST_H
+#define __WVTEST_H
+
+#ifndef WVTEST_CONFIGURED
+# error "Missing settings: HAVE_VALGRIND_MEMCHECK_H HAVE_WVCRASH WVTEST_CONFIGURED"
+#endif
+
+#include <time.h>
+#include <string.h>
+#include <stdbool.h>
+
+typedef void wvtest_mainfunc();
+
+struct WvTest {
+       const char *descr, *idstr;
+       wvtest_mainfunc *main;
+       int slowness;
+       struct WvTest *next;
+};
+
+int wvtest_run_all(char * const *prefixes);
+void wvtest_start(const char *file, int line, const char *condstr);
+void wvtest_check(bool cond, const char *reason);
+static inline bool wvtest_start_check(const char *file, int line,
+                                     const char *condstr, bool cond)
+{ wvtest_start(file, line, condstr); wvtest_check(cond, NULL); return cond; }
+bool wvtest_start_check_eq(const char *file, int line,
+                          const char *a, const char *b, bool expect_pass);
+bool wvtest_start_check_lt(const char *file, int line,
+                          const char *a, const char *b);
+int wvtest_start_check_frsh(const char *file, int line,
+                           const char *condstr, int frsh_retval);
+
+
+#define WVPASS(cond) \
+    wvtest_start_check(__FILE__, __LINE__, #cond, (cond))
+#define WVPASSEQ(a, b) \
+    wvtest_start_check_eq(__FILE__, __LINE__, (a), (b), true)
+#define WVPASSLT(a, b) \
+    wvtest_start_check_lt(__FILE__, __LINE__, (a), (b))
+#define WVFAIL(cond) \
+    wvtest_start_check(__FILE__, __LINE__, "NOT(" #cond ")", !(cond))
+#define WVFAILEQ(a, b) \
+    wvtest_start_check_eq(__FILE__, __LINE__, (a), (b), false)
+#define WVPASSNE(a, b) WVFAILEQ(a, b)
+#define WVFAILNE(a, b) WVPASSEQ(a, b)
+#define WVFRSH(frshretval) \
+       wvtest_start_check_frsh(__FILE__, __LINE__, #frshretval, (frshretval))
+
+
+#define WVTEST_MAIN3(_descr, ff, ll, _slowness)                                \
+       static void _wvtest_main_##ll();                                \
+       struct WvTest _wvtest_##ll = \
+       { .descr = _descr, .idstr = ff ":" #ll, .main = _wvtest_main_##ll, .slowness = _slowness }, \
+               *_wvtest_ptr_##ll __attribute__ ((section ("wvtest"))) = &_wvtest_##ll; \
+       static void _wvtest_main_##ll()
+#define WVTEST_MAIN2(descr, ff, ll, slowness)  \
+       WVTEST_MAIN3(descr, ff, ll, slowness)
+#define WVTEST_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 0)
+#define WVTEST_SLOW_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 1)
+
+
+#endif // __WVTEST_H
diff --git a/build/aquosa/wvtest/c/wvtestfrsh.c b/build/aquosa/wvtest/c/wvtestfrsh.c
new file mode 100644 (file)
index 0000000..cc1f276
--- /dev/null
@@ -0,0 +1,15 @@
+#include "wvtest.h"
+#include <frsh_error.h>
+
+int wvtest_start_check_frsh(const char *file, int line,
+                            const char *condstr, int frsh_retval)
+{
+       char errstr[80] = "ok";
+       wvtest_start(file, line, condstr);
+       if (frsh_retval != 0)
+               frsh_strerror (frsh_retval, errstr, sizeof(errstr));
+
+       wvtest_check(frsh_retval == 0, errstr);
+
+       return frsh_retval;
+}
diff --git a/build/aquosa/wvtest/c/wvtestmain.c b/build/aquosa/wvtest/c/wvtestmain.c
new file mode 100644 (file)
index 0000000..446e5ba
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * WvTest:
+ *   Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ *       Licensed under the GNU Library General Public License, version 2.
+ *       See the included file named LICENSE for license information.
+ */
+#include "wvtest.h"
+#ifdef HAVE_WVCRASH
+# include "wvcrash.h"
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef _WIN32
+#include <io.h>
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <fcntl.h>
+#endif
+
+static bool fd_is_valid(int fd)
+{
+#ifdef _WIN32
+    if ((HANDLE)_get_osfhandle(fd) != INVALID_HANDLE_VALUE) return true;
+#endif    
+    int nfd = dup(fd);
+    if (nfd >= 0)
+    {
+       close(nfd);
+       return true;
+    }
+    return false;
+
+}
+
+
+static int fd_count(const char *when)
+{
+    int count = 0;
+    int fd;
+    printf("fds open at %s:", when);
+    
+    for (fd = 0; fd < 1024; fd++)
+    {
+       if (fd_is_valid(fd))
+       {
+           count++;
+           printf(" %d", fd);
+           fflush(stdout);
+       }
+    }
+    printf("\n");
+    
+    return count;
+}
+
+
+int main(int argc, char **argv)
+{
+    char buf[200];
+#if defined(_WIN32) && defined(HAVE_WVCRASH)
+    setup_console_crash();
+#endif
+
+    // test wvtest itself.  Not very thorough, but you have to draw the
+    // line somewhere :)
+    WVPASS(true);
+    WVPASS(1);
+    WVFAIL(false);
+    WVFAIL(0);
+    int startfd, endfd;
+    char * const *prefixes = NULL;
+    
+    if (argc > 1)
+       prefixes = argv + 1;
+    
+    startfd = fd_count("start");
+    int ret = wvtest_run_all(prefixes);
+    
+//    if (ret == 0) // don't pollute the strace output if we failed anyway
+    if (0)
+    {
+       endfd = fd_count("end");
+    
+       WVPASS(startfd == endfd);
+#ifndef _WIN32
+       if (startfd != endfd)
+       {
+           sprintf(buf, "ls -l /proc/%d/fd", getpid());
+           system(buf);
+       }
+#endif    
+    }
+    
+    // keep 'make' from aborting if this environment variable is set
+    if (getenv("WVTEST_NO_FAIL"))
+       return 0;
+    else
+       return ret;
+}
diff --git a/build/aquosa/wvtest/cpp/Makefile.omk b/build/aquosa/wvtest/cpp/Makefile.omk
new file mode 100644 (file)
index 0000000..8bc2ce4
--- /dev/null
@@ -0,0 +1,7 @@
+
+include_HEADERS = wvtest.h
+
+CFLAGS += -DWVTEST_CONFIGURED
+
+lib_LIBRARIES = wvtest
+wvtest_SOURCES = wvtestmain.cc wvtest.cc
diff --git a/build/aquosa/wvtest/cpp/wvtest.cc b/build/aquosa/wvtest/cpp/wvtest.cc
new file mode 100644 (file)
index 0000000..6ae965d
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * WvTest:
+ *   Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ *       Licensed under the GNU Library General Public License, version 2.
+ *       See the included file named LICENSE for license information.
+ */
+#include "wvtest.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#ifdef _WIN32
+#include <direct.h>
+#else
+#include <unistd.h>
+#include <sys/wait.h>
+#endif
+#include <errno.h>
+#include <signal.h>
+#include <frsh_error.h>
+
+#include <cstdlib>
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+# include <valgrind/memcheck.h>
+# include <valgrind/valgrind.h>
+#else
+# define VALGRIND_COUNT_ERRORS 0
+# define VALGRIND_DO_LEAK_CHECK
+# define VALGRIND_COUNT_LEAKS(a,b,c,d) (a=b=c=d=0)
+#endif
+
+#define MAX_TEST_TIME 40     // max seconds for a single test to run
+#define MAX_TOTAL_TIME 120*60 // max seconds for the entire suite to run
+
+#define TEST_START_FORMAT "! %s:%-5d %-40s "
+
+static int memerrs()
+{
+    return (int)VALGRIND_COUNT_ERRORS;
+}
+
+static int memleaks()
+{
+    int leaked = 0, dubious = 0, reachable = 0, suppressed = 0;
+    VALGRIND_DO_LEAK_CHECK;
+    VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed);
+    printf("memleaks: sure:%d dubious:%d reachable:%d suppress:%d\n",
+          leaked, dubious, reachable, suppressed);
+    fflush(stdout);
+    
+    // dubious+reachable are normally non-zero because of globals...
+    // return leaked+dubious+reachable;
+    return leaked;
+}
+
+// Return 1 if no children are running or zombies, 0 if there are any running
+// or zombie children.
+// Will wait for any already-terminated children first.
+// Passes if no rogue children were running, fails otherwise.
+// If your test gets a failure in here, either you're not killing all your
+// children, or you're not calling waitpid(2) on all of them.
+static bool no_running_children()
+{
+#ifndef _WIN32
+    pid_t wait_result;
+
+    // Acknowledge and complain about any zombie children
+    do 
+    {
+       int status = 0;
+        wait_result = waitpid(-1, &status, WNOHANG);
+
+        if (wait_result > 0)
+        {
+            char buf[256];
+            snprintf(buf, sizeof(buf) - 1, "%d", wait_result);
+            buf[sizeof(buf)-1] = '\0';
+            WVFAILEQ("Unclaimed dead child process", buf);
+        }
+    } while (wait_result > 0);
+        
+    // There should not be any running children, so waitpid should return -1
+    WVPASSEQ(errno, ECHILD);
+    WVPASSEQ(wait_result, -1);
+    return (wait_result == -1 && errno == ECHILD);
+#endif
+    return true;
+}
+
+
+WvTest *WvTest::first, *WvTest::last;
+int WvTest::fails, WvTest::runs;
+time_t WvTest::start_time;
+bool WvTest::run_twice = false;
+
+void WvTest::alarm_handler(int)
+{
+    printf("\n! WvTest  Current test took longer than %d seconds!  FAILED\n",
+          MAX_TEST_TIME);
+    fflush(stdout);
+    abort();
+}
+
+
+static const char *pathstrip(const char *filename)
+{
+    const char *cptr;
+    cptr = strrchr(filename, '/');
+    if (cptr) filename = cptr + 1;
+    cptr = strrchr(filename, '\\');
+    if (cptr) filename = cptr + 1;
+    return filename;
+}
+
+
+WvTest::WvTest(const char *_descr, const char *_idstr, MainFunc *_main,
+              int _slowness) :
+    descr(_descr), 
+    idstr(pathstrip(_idstr)), 
+    main(_main), 
+    slowness(_slowness),
+    next(NULL)
+{
+    if (first)
+       last->next = this;
+    else
+       first = this;
+    last = this;
+}
+
+
+static bool prefix_match(const char *s, const char * const *prefixes)
+{
+    for (const char * const *prefix = prefixes; prefix && *prefix; prefix++)
+    {
+       if (!strncasecmp(s, *prefix, strlen(*prefix)))
+           return true;
+    }
+    return false;
+}
+
+
+int WvTest::run_all(const char * const *prefixes)
+{
+    int old_valgrind_errs = 0, new_valgrind_errs;
+    int old_valgrind_leaks = 0, new_valgrind_leaks;
+    
+#ifdef _WIN32
+    /* I should be doing something to do with SetTimer here, 
+     * not sure exactly what just yet */
+#else
+    char *disable(getenv("WVTEST_DISABLE_TIMEOUT"));
+    if (disable != NULL && disable[0] != '\0' && disable[0] != '0')
+        signal(SIGALRM, SIG_IGN);
+    else
+        signal(SIGALRM, alarm_handler);
+    alarm(MAX_TEST_TIME);
+#endif
+    start_time = time(NULL);
+    
+    // make sure we can always start out in the same directory, so tests have
+    // access to their files.  If a test uses chdir(), we want to be able to
+    // reverse it.
+    char wd[1024];
+    if (!getcwd(wd, sizeof(wd)))
+       strcpy(wd, ".");
+    
+    const char *slowstr1 = getenv("WVTEST_MIN_SLOWNESS");
+    const char *slowstr2 = getenv("WVTEST_MAX_SLOWNESS");
+    int min_slowness = 0, max_slowness = 65535;
+    if (slowstr1) min_slowness = atoi(slowstr1);
+    if (slowstr2) max_slowness = atoi(slowstr2);
+
+#ifdef _WIN32
+    run_twice = false;
+#else
+    char *parallel_str = getenv("WVTEST_PARALLEL");
+    if (parallel_str) 
+        run_twice = atoi(parallel_str) > 0;
+#endif
+
+    // there are lots of fflush() calls in here because stupid win32 doesn't
+    // flush very often by itself.
+    fails = runs = 0;
+    for (WvTest *cur = first; cur; cur = cur->next)
+    {
+       if (cur->slowness <= max_slowness
+           && cur->slowness >= min_slowness
+           && (!prefixes
+               || prefix_match(cur->idstr, prefixes)
+               || prefix_match(cur->descr, prefixes)))
+       {
+#ifndef _WIN32
+            // set SIGPIPE back to default, helps catch tests which don't set
+            // this signal to SIG_IGN (which is almost always what you want)
+            // on startup
+            signal(SIGPIPE, SIG_DFL);
+
+            pid_t child = 0;
+            if (run_twice)
+            {
+                // I see everything twice!
+                printf("Running test in parallel.\n");
+                child = fork();
+            }
+#endif
+
+           printf("\nTesting \"%s\" in %s:\n", cur->descr, cur->idstr);
+           fflush(stdout);
+           
+           cur->main();
+           chdir(wd);
+           
+           new_valgrind_errs = memerrs();
+           WVPASS(new_valgrind_errs == old_valgrind_errs);
+           old_valgrind_errs = new_valgrind_errs;
+           
+           new_valgrind_leaks = memleaks();
+           WVPASS(new_valgrind_leaks == old_valgrind_leaks);
+           old_valgrind_leaks = new_valgrind_leaks;
+           
+           fflush(stderr);
+           printf("\n");
+           fflush(stdout);
+
+#ifndef _WIN32
+            if (run_twice)
+            {
+                if (!child)
+                {
+                    // I see everything once!
+                    printf("Child exiting.\n");
+                    _exit(0);
+                }
+                else
+                {
+                    printf("Waiting for child to exit.\n");
+                    int result;
+                    while ((result = waitpid(child, NULL, 0)) == -1 && 
+                            errno == EINTR)
+                        printf("Waitpid interrupted, retrying.\n");
+                }
+            }
+#endif
+
+            WVPASS(no_running_children());
+       }
+    }
+    
+    WVPASS(runs > 0);
+    
+    if (prefixes && *prefixes && **prefixes)
+       printf("WvTest: WARNING: only ran tests starting with "
+              "specifed prefix(es).\n");
+    else
+       printf("WvTest: ran all tests.\n");
+    printf("WvTest: %d test%s, %d failure%s.\n",
+          runs, runs==1 ? "" : "s",
+          fails, fails==1 ? "": "s");
+    fflush(stdout);
+    
+    return fails != 0;
+}
+
+
+// If we aren't running in parallel, we want to output the name of the test
+// before we run it, so we know what happened if it crashes.  If we are
+// running in parallel, outputting this information in multiple printf()s
+// can confuse parsers, so we want to output everything in one printf().
+//
+// This function gets called by both start() and check().  If we're not
+// running in parallel, just print the data.  If we're running in parallel,
+// and we're starting a test, save a copy of the file/line/description until
+// the test is done and we can output it all at once.
+//
+// Yes, this is probably the worst API of all time.
+void WvTest::print_result(bool start, const char *_file, int _line, 
+                         const char *_condstr, const char *result)
+{
+    static char *file;
+    static char *condstr;
+    static int line;
+    
+    if (start)
+    {
+        if (file) 
+            free(file);
+        if (condstr) 
+            free(condstr);
+        file = strdup(pathstrip(_file));
+        condstr = strdup(_condstr);
+        line = _line;
+
+        for (char *cptr = condstr; *cptr; cptr++)
+        {
+            if (!isprint((unsigned char)*cptr))
+                *cptr = '!';
+        }
+    }
+            
+    if (run_twice)
+    {
+        if (!start)
+            printf(TEST_START_FORMAT "%s\n", file, line, condstr, result);
+    }
+    else
+    {
+        if (start)
+            printf(TEST_START_FORMAT, file, line, condstr);
+        else
+            printf("%s\n", result);
+    }
+    fflush(stdout);
+
+    if (!start)
+    {
+        if (file)
+            free(file);
+        if (condstr)
+            free(condstr);
+        file = condstr = NULL;
+    }
+}
+
+
+void WvTest::start(const char *file, int line, const char *condstr)
+{
+    // Either print the file, line, and condstr, or save them for later.
+    print_result(true, file, line, condstr, false);
+}
+
+
+void WvTest::check(bool cond, const char *reason)
+{
+#ifndef _WIN32
+    alarm(MAX_TEST_TIME); // restart per-test timeout
+#endif
+    if (!start_time) start_time = time(NULL);
+    
+    if (time(NULL) - start_time > MAX_TOTAL_TIME)
+    {
+       printf("\n! WvTest   Total run time exceeded %d seconds!  FAILED\n",
+              MAX_TOTAL_TIME);
+       fflush(stdout);
+       abort();
+    }
+    
+    runs++;
+
+    print_result(false, NULL, 0, NULL, cond ? "ok" : reason);
+
+    if (!cond)
+    {
+       fails++;
+       
+       if (getenv("WVTEST_DIE_FAST"))
+           abort();
+    }
+}
+
+
+bool WvTest::start_check_eq(const char *file, int line,
+                           const char *a, const char *b, bool expect_pass)
+{
+    if (!a) a = "";
+    if (!b) b = "";
+    
+    size_t len = strlen(a) + strlen(b) + 8 + 1;
+    char *str = new char[len];
+    sprintf(str, "[%s] %s [%s]", a, expect_pass ? "==" : "!=", b);
+    
+    start(file, line, str);
+    delete[] str;
+    
+    bool cond = !strcmp(a, b);
+    if (!expect_pass)
+        cond = !cond;
+
+    check(cond);
+    return cond;
+}
+
+
+bool WvTest::start_check_eq(const char *file, int line,
+                           const std::string &a, const std::string &b, 
+                            bool expect_pass)
+{
+    return start_check_eq(file, line, a.c_str(), b.c_str(), expect_pass);
+}
+
+
+bool WvTest::start_check_eq(const char *file, int line, 
+                            int a, int b, bool expect_pass)
+{
+    size_t len = 128 + 128 + 8 + 1;
+    char *str = new char[len];
+    sprintf(str, "%d %s %d", a, expect_pass ? "==" : "!=", b);
+    
+    start(file, line, str);
+    delete[] str;
+    
+    bool cond = (a == b);
+    if (!expect_pass)
+        cond = !cond;
+
+    check(cond);
+    return cond;
+}
+
+
+bool WvTest::start_check_lt(const char *file, int line,
+                           const char *a, const char *b)
+{
+    if (!a) a = "";
+    if (!b) b = "";
+    
+    size_t len = strlen(a) + strlen(b) + 8 + 1;
+    char *str = new char[len];
+    sprintf(str, "[%s] < [%s]", a, b);
+    
+    start(file, line, str);
+    delete[] str;
+
+    bool cond = strcmp(a, b) < 0;
+    check(cond);
+    return cond;
+}
+
+
+bool WvTest::start_check_lt(const char *file, int line, int a, int b)
+{
+    size_t len = 128 + 128 + 8 + 1;
+    char *str = new char[len];
+    sprintf(str, "%d < %d", a, b);
+    
+    start(file, line, str);
+    delete[] str;
+    
+    bool cond = a < b;
+    check(cond);
+    return cond;
+}
+
+int WvTest::start_check_frsh(const char *file, int line,
+                            const char *condstr, int frsh_retval)
+{
+       char errstr[80] = "ok";
+       start(file, line, condstr);
+       if (frsh_retval != 0)
+               frsh_strerror (frsh_retval, errstr, sizeof(errstr));
+
+       check(frsh_retval == 0, errstr);
+
+       return frsh_retval;
+}
diff --git a/build/aquosa/wvtest/cpp/wvtest.h b/build/aquosa/wvtest/cpp/wvtest.h
new file mode 100644 (file)
index 0000000..287e3fb
--- /dev/null
@@ -0,0 +1,88 @@
+/* -*- Mode: C++ -*-
+ * WvTest:
+ *   Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ *       Licensed under the GNU Library General Public License, version 2.
+ *       See the included file named LICENSE for license information.
+ */ 
+#ifndef __WVTEST_H
+#define __WVTEST_H
+
+#ifndef WVTEST_CONFIGURED
+# error "Missing settings: HAVE_VALGRIND_MEMCHECK_H HAVE_WVCRASH WVTEST_CONFIGURED"
+#endif
+
+#include <time.h>
+#include <string>
+
+class WvTest
+{
+    typedef void MainFunc();
+    const char *descr, *idstr;
+    MainFunc *main;
+    int slowness;
+    WvTest *next;
+    static WvTest *first, *last;
+    static int fails, runs;
+    static time_t start_time;
+    static bool run_twice;
+    
+    static void alarm_handler(int sig);
+   
+    static void
+    print_result(bool start, const char *file, int line, 
+                const char *condstr, const char *result);
+
+    static inline void
+    print_result(bool start, const char *file, int line, 
+                const char *condstr, bool result)
+       { print_result(start, file, line, condstr, result ? "ok" : "FAILED"); }
+public:
+    WvTest(const char *_descr, const char *_idstr, MainFunc *_main, int _slow);
+    static int run_all(const char * const *prefixes = NULL);
+    static void start(const char *file, int line, const char *condstr);
+    static void check(bool cond, const char *reason = "FAILED");
+    static inline bool start_check(const char *file, int line,
+                                  const char *condstr, bool cond)
+        { start(file, line, condstr); check(cond); return cond; }
+    static bool start_check_eq(const char *file, int line,
+                              const char *a, const char *b, bool expect_pass);
+    static bool start_check_eq(const char *file, int line,
+                              const std::string &a, const std::string &b, 
+                               bool expect_pass);
+    static bool start_check_eq(const char *file, int line, int a, int b,
+                               bool expect_pass);
+    static bool start_check_lt(const char *file, int line,
+                               const char *a, const char *b);
+    static bool start_check_lt(const char *file, int line, int a, int b);
+    static int start_check_frsh(const char *file, int line,
+                               const char *condstr, int frsh_retval);
+};
+
+
+#define WVPASS(cond) \
+    WvTest::start_check(__FILE__, __LINE__, #cond, (cond))
+#define WVPASSEQ(a, b) \
+    WvTest::start_check_eq(__FILE__, __LINE__, (a), (b), true)
+#define WVPASSLT(a, b) \
+    WvTest::start_check_lt(__FILE__, __LINE__, (a), (b))
+#define WVFAIL(cond) \
+    WvTest::start_check(__FILE__, __LINE__, "NOT(" #cond ")", !(cond))
+#define WVFAILEQ(a, b) \
+    WvTest::start_check_eq(__FILE__, __LINE__, (a), (b), false)
+#define WVPASSNE(a, b) WVFAILEQ(a, b)
+#define WVFAILNE(a, b) WVPASSEQ(a, b)
+#define WVFRSH(frshretval) \
+       WvTest::start_check_frsh(__FILE__, __LINE__, #frshretval, (frshretval))
+
+
+#define WVTEST_MAIN3(descr, ff, ll, slowness) \
+    static void _wvtest_main_##ll(); \
+    static WvTest _wvtest_##ll(descr, ff, _wvtest_main_##ll, slowness); \
+    static void _wvtest_main_##ll()
+#define WVTEST_MAIN2(descr, ff, ll, slowness) \
+    WVTEST_MAIN3(descr, ff, ll, slowness)
+#define WVTEST_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 0)
+#define WVTEST_SLOW_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 1)
+
+
+#endif // __WVTEST_H
diff --git a/build/aquosa/wvtest/cpp/wvtestmain.cc b/build/aquosa/wvtest/cpp/wvtestmain.cc
new file mode 100644 (file)
index 0000000..b44dfb5
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * WvTest:
+ *   Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ *       Licensed under the GNU Library General Public License, version 2.
+ *       See the included file named LICENSE for license information.
+ */
+#include "wvtest.h"
+#ifdef HAVE_WVCRASH
+# include "wvcrash.h"
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef _WIN32
+#include <io.h>
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <fcntl.h>
+#endif
+
+static bool fd_is_valid(int fd)
+{
+#ifdef _WIN32
+    if ((HANDLE)_get_osfhandle(fd) != INVALID_HANDLE_VALUE) return true;
+#endif    
+    int nfd = dup(fd);
+    if (nfd >= 0)
+    {
+       close(nfd);
+       return true;
+    }
+    return false;
+
+}
+
+
+static int fd_count(const char *when)
+{
+    int count = 0;
+    
+    printf("fds open at %s:", when);
+    
+    for (int fd = 0; fd < 1024; fd++)
+    {
+       if (fd_is_valid(fd))
+       {
+           count++;
+           printf(" %d", fd);
+           fflush(stdout);
+       }
+    }
+    printf("\n");
+    
+    return count;
+}
+
+
+int main(int argc, char **argv)
+{
+    char buf[200];
+#if defined(_WIN32) && defined(HAVE_WVCRASH)
+    setup_console_crash();
+#endif
+
+    // test wvtest itself.  Not very thorough, but you have to draw the
+    // line somewhere :)
+    WVPASS(true);
+    WVPASS(1);
+    WVFAIL(false);
+    WVFAIL(0);
+    int startfd, endfd;
+    char * const *prefixes = NULL;
+    
+    if (argc > 1)
+       prefixes = argv + 1;
+    
+    startfd = fd_count("start");
+    int ret = WvTest::run_all(prefixes);
+    
+    if (ret == 0) // don't pollute the strace output if we failed anyway
+    {
+       endfd = fd_count("end");
+    
+       WVPASS(startfd == endfd);
+#ifndef _WIN32
+       if (startfd != endfd)
+       {
+           sprintf(buf, "ls -l /proc/%d/fd", getpid());
+           system(buf);
+       }
+#endif    
+    }
+    
+    // keep 'make' from aborting if this environment variable is set
+    if (getenv("WVTEST_NO_FAIL"))
+       return 0;
+    else
+       return ret;
+}
diff --git a/build/aquosa/wvtestrun b/build/aquosa/wvtestrun
new file mode 120000 (symlink)
index 0000000..eebe3b7
--- /dev/null
@@ -0,0 +1 @@
+../../src/wvtest/wvtestrun
\ No newline at end of file
similarity index 100%
rename from src/tests/Makefile
rename to build/marte/Makefile
diff --git a/build/marte/Makefile.omk b/build/marte/Makefile.omk
new file mode 100644 (file)
index 0000000..c459c78
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS=$(ALL_OMK_SUBDIRS)
diff --git a/build/marte/Makefile.rules b/build/marte/Makefile.rules
new file mode 100644 (file)
index 0000000..b020a32
--- /dev/null
@@ -0,0 +1,1356 @@
+#                   Version for Linux/RTLinux builds.        #OMK@linux
+#
+#  Makefile.rules - OCERA make framework common project rules -*- makefile -*- #OMK@base
+#
+#  (C) Copyright 2003 by Pavel Pisa - OCERA team member
+#  (C) Copyright 2006 by Michal Sojka - Czech Technical University, FEE, DCE
+#
+#  Homepage: http://rtime.felk.cvut.cz/omk/
+#
+# The OMK build system is distributed under the GNU General Public
+# License.  See file COPYING for details.
+#
+# input variables
+# V                .. if set to 1, full command text is shown else short form is used
+# W                .. whole tree - if set to 1, make is always called from the top-level directory
+# SUBDIRS          .. list of subdirectories intended for make from actual directory
+# default_CONFIG   .. list of default config assignments CONFIG_XXX=y/n ...
+# LN_HEADERS       .. if "y", header files are symbolicaly linked instead of copied. #OMK@include
+#                                                            #OMK@linux
+# input variables
+# lib_LIBRARIES    .. list of the user-space libraries
+# shared_LIBRARIES .. list of the user-space shared libraries
+# kernel_LIBRARIES .. list of the kernel-space libraries
+# rtlinux_LIBRARIES.. list of the RT-Linux kernel-space libraries
+# include_HEADERS  .. list of the user-space public header files
+# nobase_include_HEADERS .. public headers copied even with directory part
+# renamed_include_HEADERS .. public headers copied to the different target name
+# kernel_HEADERS   .. list of the kernel-space public header files
+# rtlinux_HEADERS  .. list of the RT-Linux kernel-space public header files
+# bin_PROGRAMS     .. list of the require binary programs
+# utils_PROGRAMS   .. list of the development utility programs
+# test_PROGRAMS    .. list of the testing programs
+# kernel_MODULES   .. list of the kernel side modules/applications
+# rtlinux_MODULES  .. list of RT-Linux the kernel side modules/applications
+# xxx_SOURCES      .. list of specific target sources
+# xxx_LIBS         .. list of specific target libraries
+# INCLUDES         .. additional include directories and defines for user-space
+# kernel_INCLUDES  .. additional include directories and defines for kernel-space
+# rtlinux_INCLUDES .. additional include directories and defines for RT-Linux
+# OMIT_KERNEL_PASSES  if defined, all kernel passes are omited
+#
+# LINUX_DIR        .. location of Linux kernel sources
+# RTL_DIR          .. location of RT-Linux sources
+# CFLAGS           .. C compiler flags
+# CXXFLAGS         .. C++ compiler flags
+# CPPFLAGS        .. C preprocessor flags
+# LDFLAGS         .. linker flags for programs linking
+# LOCAL_CONFIG_H   .. name of local config.h file generated from values #OMK@config_h
+#                     of options defined in the current directory
+# config_include_HEADERS .. names of global config files (possibly
+#                     with subdirectories)
+# xxx_DEFINES      .. list of config directives to be included in
+#                     config header file of the name <somedir>/xxx.h
+# DOXYGEN          .. if non-empty, generated headers includes Doxygen's @file
+#                    command, so it is possible to document config
+#                    variables.
+# QT_SUBDIRS       .. subdirectories where to build QT applications using qmake #OMK@qt
+# QTDIR                   .. where QT resides
+OMK_RULES_TYPE=linux                                         #OMK@__type
+                                                             #OMK@base
+# We need to ensure definition of sources directory first
+ifndef SOURCES_DIR
+# Only shell built-in pwd understands -L
+SOURCES_DIR := $(shell ( pwd -L ) )
+endif
+
+# If we are not called by OMK leaf Makefile...
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(abspath $(dir $(filter %Makefile.rules,$(MAKEFILE_LIST))))
+endif
+
+# OUTPUT_DIR is the place where _compiled, _build and possible other
+# files/directories are created. By default is the same as
+# $(MAKERULES_DIR).
+ifndef OUTPUT_DIR
+OUTPUT_DIR := $(MAKERULES_DIR)
+endif
+
+.PHONY: all default check-make-ver omkize
+
+ifdef W
+  ifeq ("$(origin W)", "command line")
+    OMK_WHOLE_TREE:=$(W)
+  endif
+endif
+ifndef OMK_WHOLE_TREE
+  OMK_WHOLE_TREE:=0
+endif
+
+ifneq ($(OMK_WHOLE_TREE),1)
+all: check-make-ver default
+       @echo "Compilation finished"
+else
+# Run make in the top-level directory
+all:
+       @$(MAKE) -C $(MAKERULES_DIR) OMK_SERIALIZE_INCLUDED=n SOURCES_DIR=$(MAKERULES_DIR) RELATIVE_DIR="" $(MAKECMDGOALS) W=0
+endif
+
+ifdef OMK_TESTSROOT
+# Usage: $(call canttest,<error message>)
+define canttest
+       ( echo "$(1)" > $(OUTPUT_DIR)/_canttest; echo "$(1)"; exit 1 )
+endef
+else
+define canttest
+       echo "$(1)"
+endef
+endif
+
+#=========================
+# Include the config file
+
+# FIXME: I think CONFIG_FILE_OK variable is useless. We have three
+# config files and it is not clearly defined to which file is this
+# variable related.
+ifneq ($(CONFIG_FILE_OK),y)
+ifndef CONFIG_FILE
+CONFIG_FILE      := $(OUTPUT_DIR)/config.omk
+endif
+ifneq ($(wildcard $(CONFIG_FILE)-default),)
+-include $(CONFIG_FILE)-default
+else
+ifneq ($(MAKECMDGOALS),default-config)
+$(warning Please, run "make default-config" first)
+endif
+endif
+
+-include $(OUTPUT_DIR)/config.target
+
+ifneq ($(wildcard $(CONFIG_FILE)),)
+-include $(CONFIG_FILE)
+CONFIG_FILE_OK = y
+endif
+endif #$(CONFIG_FILE_OK)
+
+
+CONFIG_FILES ?= $(wildcard $(CONFIG_FILE)-default) $(wildcard $(OUTPUT_DIR)/config.target) $(wildcard $(CONFIG_FILE))
+
+
+export SOURCES_DIR MAKERULES_DIR RELATIVE_DIR
+export CONFIG_FILE CONFIG_FILES OMK_SERIALIZE_INCLUDED OMK_VERBOSE OMK_SILENT
+# OMK_SERIALIZE_INCLUDED has to be exported to submakes because passes
+# must to be serialized only in the toplevel make.
+
+ifndef RELATIVE_DIR
+RELATIVE_DIR := $(SOURCES_DIR:$(OUTPUT_DIR)%=%)
+endif
+#$(warning  === RELATIVE_DIR = "$(RELATIVE_DIR)" ===)
+override RELATIVE_DIR := $(RELATIVE_DIR:/%=%)
+override RELATIVE_DIR := $(RELATIVE_DIR:\\%=%)
+#$(warning  RELATIVE_DIR = "$(RELATIVE_DIR)")
+override BACK2TOP_DIR := $(shell echo $(RELATIVE_DIR)/ | sed -e 's_//_/_g' -e 's_/\./_/_g' -e 's_^\./__g'  -e 's_\([^/][^/]*\)_.._g' -e 's_/$$__')
+#$(warning  BACK2TOP_DIR = "$(BACK2TOP_DIR)")
+
+#$(warning SOURCES_DIR = "$(SOURCES_DIR)")
+#$(warning MAKERULES_DIR = "$(OUTPUT_DIR)")
+#$(warning RELATIVE_DIR = "$(RELATIVE_DIR)")
+
+# We have to use RELATIVE_PREFIX because of mingw
+override RELATIVE_PREFIX := $(RELATIVE_DIR)/
+override RELATIVE_PREFIX := $(RELATIVE_PREFIX:/%=%)
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+# Define srcdir for Automake compatibility
+srcdir = $(SOURCES_DIR)
+
+# Defines for quiet compilation
+ifdef V
+  ifeq ("$(origin V)", "command line")
+    OMK_VERBOSE = $(V)
+  endif
+endif
+ifndef OMK_VERBOSE
+  OMK_VERBOSE = 0
+endif
+ifneq ($(OMK_VERBOSE),0)
+  Q =
+else
+  Q = @
+endif
+ifneq ($(findstring s,$(MAKEFLAGS)),)
+  QUIET_CMD_ECHO = true
+  OMK_SILENT = 1
+else
+  QUIET_CMD_ECHO = echo
+endif
+
+MAKEFILE_OMK=Makefile.omk
+# All subdirectories (even linked ones) containing Makefile.omk
+# Usage in Makefile.omk: SUBDIRS = $(ALL_OMK_SUBDIRS)
+ALL_OMK_SUBDIRS = $(patsubst %/$(MAKEFILE_OMK),%,$(patsubst $(SOURCES_DIR)/%,%,$(wildcard $(SOURCES_DIR)/*/$(MAKEFILE_OMK))))
+
+# ===================================================================
+# We have set up all important variables, so we can check and include
+# real OCERA style Makefile.omk now
+ifndef OMK_INCLUDED
+include $(SOURCES_DIR)/$(MAKEFILE_OMK)
+ifeq ($(AUTOMATIC_SUBDIRS),y)
+SUBDIRS?=$(ALL_OMK_SUBDIRS)
+endif
+OMK_INCLUDED := 1
+endif
+
+check-make-ver:
+       @GOOD_MAKE_VERSION=`echo $(MAKE_VERSION) | sed -n -e 's/^[4-9]\..*\|^3\.9[0-9].*\|^3\.8[1-9].*/y/p'` ; \
+       if [ x$$GOOD_MAKE_VERSION != xy ] ; then \
+               echo "Your make program version is too old and does not support OMK system." ; \
+               echo "Please update to make program 3.81beta1 or newer." ; exit 1 ; \
+       fi
+
+distclean dist-clean:
+       @$(QUIET_CMD_ECHO) "  RM      $(COMPILED_DIR_NAME) $(BUILD_DIR_NAME)"
+       @rm -fr $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)  $(OUTPUT_DIR)/$(BUILD_DIR_NAME)
+
+# Common OMK templates
+# ====================
+
+# Syntax: $(call mkdir,<dir name>)
+define mkdir_def
+       [ -d $(1) ] || mkdir -p $(1) || exit 1
+endef
+
+ifneq ($(OMK_VERBOSE),2)
+NO_PRINT_DIRECTORY := --no-print-directory
+endif
+
+ifeq ($(USE_LEAF_MAKEFILES),n)
+export USE_LEAF_MAKEFILES
+SUBDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+SOURCESDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+else
+SUBDIR_MAKEFILE=$(SOURCES_DIR)/$(3)/Makefile
+SOURCESDIR_MAKEFILE=$(SOURCES_DIR)/Makefile
+endif
+
+pass = $(strip $(1))
+
+# Call a pass in a subdirectory
+# Usage: $(call omk_pass_subdir_template,<pass name>,<build dir>,<subdir>)
+define omk_pass_subdir_template
+.PHONY: $(pass)-$(3)-subdir
+$(pass)-submakes: $(pass)-$(3)-subdir
+$(pass)-$(3)-subdir:
+       @$(call mkdir_def,$(2)/$(3))
+       +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(3) $(NO_PRINT_DIRECTORY) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(3) -C $(2)/$(3) \
+               -f $(SUBDIR_MAKEFILE) $(pass)-submakes
+# In subdirectories we can call submakes directly since passes are
+# already searialized on the toplevel make.
+endef
+
+ifdef OMK_TESTSROOT
+check-target = $(1:%=%-check)
+endif
+
+# Call a pass in a subdirectory
+# Usage: $(call extra_rules_subdir_template,<subdir>)
+define extra_rules_subdir_template
+extra-rules-subdirs: extra-rules-$(1)
+extra-rules-$(1):
+       +@$(MAKE) OMK_SERIALIZE_INCLUDED=n MAKERULES_DIR=$(SOURCES_DIR)/$(1) OUTPUT_DIR=$(OUTPUT_DIR) \
+               SOURCES_DIR=$(SOURCES_DIR)/$(1) RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) -C $(SOURCES_DIR)/$(1)
+endef
+
+.PHONY: extra-rules-subdirs
+extra-rules-subdirs:
+
+$(foreach subdir,$(EXTRA_RULES_SUBDIRS),$(eval $(call extra_rules_subdir_template,$(subdir))))
+
+# Usage: $(call omk_pass_template,<pass name>,<build dir>,[<local make flags>],[<local enable condition>])
+define omk_pass_template
+.PHONY: $(pass) $(pass)-local $(pass)-check $(pass)-submakes
+$(foreach subdir,$(SUBDIRS),$(eval $(call omk_pass_subdir_template,$(pass),$(2),$(subdir))))
+$(pass):
+# Submakes have to be called this way and not as dependecies for pass
+# serialization to work
+       +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR) $(NO_PRINT_DIRECTORY) \
+               RELATIVE_DIR=$(RELATIVE_DIR) \
+               -f $(SOURCESDIR_MAKEFILE) $(pass)-submakes
+$(pass)-submakes:
+       @true                   # Do not emit "nothing to be done" messages
+
+ifneq ($(4)$($(pass)_HOOKS),)
+$(pass)-submakes: $(pass)-this-dir
+$(pass)-this-dir: $(foreach subdir,$(SUBDIRS),$(pass)-$(subdir)-subdir)
+       +@echo "make[omk]: $(pass) in $(RELATIVE_DIR)"
+       @$(call mkdir_def,$(2))
+       +@$(MAKE) $(NO_PRINT_DIRECTORY) SOURCES_DIR=$(SOURCES_DIR) RELATIVE_DIR=$(RELATIVE_DIR) -C $(2) \
+               -f $(SOURCESDIR_MAKEFILE) $(3) $(check-target) $(1:%=%-local)
+$(pass)-local: $($(pass)_HOOKS)
+endif
+endef
+
+# =======================
+# DEFAULT CONFIG PASS
+
+default-config:
+       @echo "# Start of OMK config file" > "$(CONFIG_FILE)-default"
+       @echo "# This file should not be altered manually" >> "$(CONFIG_FILE)-default"
+       @echo "# Overrides should be stored in file $(notdir $(CONFIG_FILE))" >> "$(CONFIG_FILE)-default"
+       @echo >> "$(CONFIG_FILE)-default"
+       @$(MAKE) $(NO_PRINT_DIRECTORY) -C $(OUTPUT_DIR) \
+               RELATIVE_DIR="" SOURCES_DIR=$(OUTPUT_DIR) \
+               -f $(OUTPUT_DIR)/Makefile default-config-pass
+
+$(eval $(call omk_pass_template,default-config-pass,$$(LOCAL_BUILD_DIR),,always))
+
+default-config-pass-local:
+#      @echo Default config for $(RELATIVE_DIR)
+       @echo "# Config for $(RELATIVE_DIR)" >> "$(CONFIG_FILE)-default"
+       @$(foreach x, $(default_CONFIG), echo '$(x)' | \
+               sed -e 's/^[^=]*=x$$/#\0/' >> "$(CONFIG_FILE)-default" ; )
+
+
+omkize:
+       $(Q)if ! grep -q MAKERULES_DIR Makefile; then \
+          echo "Makefile is not OMK leaf makefile!" >&2; exit 1; \
+       fi
+       $(Q)for i in `find -L . -name Makefile.omk` ; do \
+          d=`dirname $${i}`; \
+          if ! test -f "$${d}/Makefile.rules" && ( ! test -f "$${d}/Makefile" || ! cmp --silent Makefile "$${d}/Makefile" ); then \
+             rm -f "$${d}/Makefile"; \
+             cp -v Makefile "$${d}/Makefile"; \
+          fi \
+       done
+ifeq ($(OMK_VERBOSE),1)                                      #OMK@include
+CPHEADER_FLAGS += -v
+LNHEADER_FLAGS += -v
+endif
+
+ifneq ($(LN_HEADERS),y)
+define cp_cmd
+( echo "  CP      $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; cp $(CPHEADER_FLAGS) $(1) $(2) )
+endef
+else
+define cp_cmd
+( echo "  LN      $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; [ -f $(1) ] && ln -sf $(LNHEADER_FLAGS) $(1) $(2) )
+endef
+endif
+
+# TODO: Check modification date of changed header files. If it is
+# newer that in source dir, show a warning.
+
+# Syntax: $(call include-pass-template,<include dir>,<keyword>)
+define include-pass-template
+include-pass-local: include-pass-local-$(2)
+include-pass-local-$(2): $$($(2)_GEN_HEADERS) $$(foreach f,$$(renamed_$(2)_GEN_HEADERS),$$(shell echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'))
+       @$$(foreach f, $$($(2)_HEADERS), cmp --quiet $$(SOURCES_DIR)/$$(f) $(1)/$$(notdir $$(f)) \
+          || $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(notdir $$(f))) || exit 1 ; )
+       @$$(foreach f, $$($(2)_GEN_HEADERS), cmp --quiet $$(f) $(1)/$$(notdir $$(f)) \
+          || $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$(f),$(1)/$$(notdir $$(f))) || exit 1 ; ) # FIXME: Use correct build dir, then document it
+       @$$(foreach f, $$(nobase_$(2)_HEADERS), cmp --quiet $$(SOURCES_DIR)/$$(f) $(1)/$$(f) \
+          || ( mkdir -p $(1)/$$(dir $$(f)) && $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(f)) ) || exit 1 ; )
+       @$$(foreach f, $$(renamed_$(2)_HEADERS), \
+          srcfname=`echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'` ; destfname=`echo '$$(f)' | sed -e 's/^.*->\(.*\)$$$$/\1/'` ; \
+          cmp --quiet $$(SOURCES_DIR)/$$$${srcfname} $(1)/$$$${destfname} \
+          || ( mkdir -p `dirname $(1)/$$$${destfname}` && $$(call cp_cmd,$$(SOURCES_DIR)/$$$${srcfname},$(1)/$$$${destfname}) ) || exit 1 ; )
+       @$$(foreach f, $$(renamed_$(2)_GEN_HEADERS), \
+          srcfname=`echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'` ; destfname=`echo '$$(f)' | sed -e 's/^.*->\(.*\)$$$$/\1/'` ; \
+          cmp --quiet $$$${srcfname} $(1)/$$$${destfname} \
+          || ( mkdir -p `dirname $(1)/$$$${destfname}` && $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$$${srcfname},$(1)/$$$${destfname}) ) || exit 1 ; )
+endef
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@linux
+# Hack to check RT-Linux rules
+#LINUX_DIR := /home/cvs/ocera/ocera-build/kernel/linux
+#RTL_DIR := /home/cvs/ocera/ocera-build/kernel/rtlinux
+#CONFIG_RTLINUX = y
+#OCERA_DIR := $(shell ( cd -L $(OUTPUT_DIR)/../../.. ; pwd -L ) )
+
+-include $(OUTPUT_DIR)/OCERA_TOP_DIR
+
+BUILD_DIR_NAME = _build
+COMPILED_DIR_NAME = _compiled
+ifndef GROUP_DIR_NAME
+GROUP_DIR_NAME = nogroup
+endif
+
+ifdef OCERA_DIR
+ifeq ($(wildcard $(OCERA_DIR)/ocera.mk),)
+$(warning "ocera.mk" file does not exist. Adapt Makefile.rules for standalone compilation)
+$(warning (comment out definition of OCERA_DIR line and optionally select RTL_DIR) )
+$(error or go to the ocera/ directory and do 'make' to generate the "ocera.mk" file first, please)
+endif
+include $(OCERA_DIR)/ocera.mk
+KERN_INCLUDE_DIR := $(OCERA_KERNEL_INCLUDES_DIR)
+KERN_LIB_DIR     := $(OCERA_KERNEL_LIBRARIES_DIR)
+KERN_MODULES_DIR := $(OCERA_MODULES_DIR)
+KERN_BUILD_DIR   := $(BUILD_DIR)/kern/$(GROUP_DIR_NAME)
+KERN_MODPOST_DIR := $(BUILD_DIR)/kern-modpost
+USER_INCLUDE_DIR := $(OCERA_USER_INCLUDES_DIR)
+USER_LIB_DIR     := $(OCERA_USER_LIBRARIES_DIR)
+USER_UTILS_DIR   := $(TARGET_DIR)/usr/bin
+USER_TESTS_DIR   := $(TARGET_DIR)/usr/bin
+USER_BIN_DIR     := $(TARGET_DIR)/usr/bin
+USER_BUILD_DIR   := $(BUILD_DIR)/user/$(GROUP_DIR_NAME)
+#LINUX_DIR        := $(OCERA_DIR)/kernel/linux
+#RTL_DIR          := $(OCERA_DIR)/kernel/rtlinux
+#CONFIG_FILE      := $(OCERA_DIR)/emdebsys/.config 
+ifneq ($(wildcard $(CONFIG_FILE)),)
+CONFIG_FILE_OK = y
+endif
+else # OCERA_DIR
+KERN_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include-kern
+KERN_LIB_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib-kern
+KERN_MODULES_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/modules
+KERN_BUILD_DIR   := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern
+KERN_MODPOST_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern-modpost
+USER_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include
+USER_LIB_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib
+USER_UTILS_DIR   := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-utils
+USER_TESTS_DIR   := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-tests
+USER_BIN_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin
+USER_BUILD_DIR   := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/user
+
+ifndef LINUX_VERSION
+LINUX_VERSION=$(shell uname -r)
+endif
+ifndef LINUX_DIR
+LINUX_DIR=/lib/modules/$(LINUX_VERSION)/build
+endif
+endif # OCERA_DIR
+
+ifeq ($(BUILD_OS),)
+  # Check for target
+  ifeq ($(OS),Windows_NT)
+    BUILD_OS := win32
+  else
+    BUILD_OS := $(shell uname | tr '[A-Z]' '[a-z]' )
+    #$(warning BUILD_OS=$(BUILD_OS))
+  endif
+endif
+
+ifeq ($(TARGET_OS),)
+  TARGET_OS := $(BUILD_OS)
+endif
+
+export TARGET_OS
+export BUILD_OS
+
+LOCAL_BUILD_DIR  = $(USER_OBJS_DIR)
+
+# Assign default values to CFLAGS variable. If the variable is defined
+# earlier (i.g. in config.omk), it is not overriden here.
+CFLAGS ?= -O2 -Wall
+CXXFLAGS ?= -O2 -Wall
+
+
+CPPFLAGS  += -I $(USER_INCLUDE_DIR)
+
+LOADLIBES += -L$(USER_LIB_DIR) 
+
+LOADLIBES += $(lib_LOADLIBES:%=-l%)
+
+LIB_CPPFLAGS += $(CPPFLAGS)
+LIB_CFLAGS   += $(CFLAGS)
+
+ifeq ($(TARGET_OS),win32)
+  SOLIB_EXT = dll
+else
+  SOLIB_EXT = so
+  SOLIB_PICFLAGS += -fpic
+endif
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+USER_OBJS_DIR = $(USER_BUILD_DIR)/$(RELATIVE_DIR)
+KERN_OBJS_DIR = $(KERN_BUILD_DIR)/$(RELATIVE_DIR)
+
+.PHONY: dep subdirs clean clean-custom cleandepend check-dir
+
+# Some support to serialize some targets for parallel make
+ifneq ($(OMK_SERIALIZE_INCLUDED),y)
+include-pass: check-dir
+library-pass: include-pass
+binary-pass: library-pass
+kernel-lib-pass: include-pass
+kernel-mod-pass: kernel-lib-pass
+kernel-modpost-pass: kernel-mod-pass
+kernel-pass: kernel-mod-pass kernel-modpost-pass
+
+override OMK_SERIALIZE_INCLUDED = y
+MAKEOVERRIDES := $(filter-out OMK_SERIALIZE_INCLUDED=n,$(MAKEOVERRIDES))
+endif
+
+# Checks for OMK tester
+ifdef OMK_TESTSROOT
+default-config-pass-check include-pass-check:
+library-pass-check binary-pass-check:
+       @[ -x "$(shell which $(CC))" ] || $(call canttest,Cannot find compiler: $(CC))
+endif
+
+#=====================================================================
+# User-space rules and templates to compile programs, libraries etc.
+
+ifdef USER_RULE_TEMPLATES
+
+USER_SOURCES2OBJS = .o/.c .o/.cc .o/.cxx .o/.S .o/.o
+
+USER_SOURCES2OBJSLO = .lo/.c .lo/.cc .lo/.cxx .lo/.S .lo/.lo
+
+#%.lo: %.c
+#      $(CC) -o $@ $(LCFLAGS) -c $<
+
+c_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+cc_o_COMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+S_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(ASFLAGS) -DOMK_FOR_USER
+
+idl_COMPILE = $(IDL_COMPILER)
+
+# Check GCC version for user build
+ifndef CC_MAJOR_VERSION
+CC_MAJOR_VERSION := $(shell $(CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(CC_MAJOR_VERSION),2)
+CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+
+# Syntax: $(call COMPILE_c_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_c_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  CC      $$@"
+       $(Q) if $$(c_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call COMPILE_cc_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_cc_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  CXX     $$@"
+       $(Q) if $$(cc_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call COMPILE_S_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_S_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  AS      $$@"
+       $(Q) if $$(S_o_COMPILE) -D__ASSEMBLY__ $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call CMETRIC_o_h_template,<object_file>,<target_header>)
+define CMETRIC_o_h_template
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CMETRIC $$@"
+       $(Q)if [ -n `dirname $$@` ] ; then \
+             if [ ! -e `dirname $$@` ] ; then \
+               mkdir -p `dirname $$@` ; fi ; fi
+       $(Q)echo >$$@ '/* Automatically generated from $$< */'
+       $(Q)echo >>$$@ '/* Conditionals to control compilation */'
+       $(Q)set -o pipefail ; $(NM) $$< \
+               | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2cond_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+               | sort >>$$@
+       $(Q)echo >>$$@ '/* Defines from the values defined to symbols */'
+       $(Q)set -o pipefail ; $(NM) $$< \
+               | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2def_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+               | sort >>$$@
+endef
+
+
+
+define COMPILE_idl_template
+$(2).c $(2)-stubs.c $(2)-skels.c $(2)-common.c $(2).h: $(1)
+       @$(QUIET_CMD_ECHO) "  IDL     $$@"
+       $(Q) $$(idl_COMPILE) $$($(2)_IDLFLAGS) $(1)
+endef
+
+
+# Syntax: $(call PROGRAM_template,<dir>,<executable-name>,<executable-suffix>,<linker-sript>)
+# FIXME: ???????? asi je tu blbej komentar
+define PROGRAM_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS  += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(2)/$(1)$(3): $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  LINK    $$@"
+       $(Q) $$(if $$(filter %.cc,$$($(1)_SOURCES:%.cxx=%.cc)),$$(CXX),$$(CC)) \
+         $$($(1)_OBJS) $$($(1)_LIBS:%=-l%) $$(LOADLIBES) $$(LDFLAGS) -Wl,-Map,$(USER_OBJS_DIR)/$(1).exe.map -o $$@
+       @echo "$(2)/$(1)$(3): \\" >$(USER_OBJS_DIR)/$(1).exe.d
+       @sed -n -e 's|^LOAD \(.*\)$$$$|  \1  \&|p' $(USER_OBJS_DIR)/$(1).exe.map|tr '&' '\134'  >>$(USER_OBJS_DIR)/$(1).exe.d
+       @echo >>$(USER_OBJS_DIR)/$(1).exe.d
+endef
+
+
+# Syntax: $(call LIBRARY_template,<library-name>)
+define LIBRARY_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS  += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(USER_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  AR      $$@"
+       $(Q) $(AR) rcs $$@ $$^
+endef
+
+
+# Syntax: $(call SOLIB_template,<library-name>)
+define SOLIB_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+SOLIB_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJSLO),
+$(1)_OBJSLO += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJSLO := $$(sort $$($(1)_OBJSLO:%/=%))
+
+SOLIB_OBJS  += $$($(1)_OBJSLO)
+SOLIB_SOURCES += $$($(1)_SOURCES)
+
+$(USER_LIB_DIR)/lib$(1).$(SOLIB_EXT): $$($(1)_OBJSLO)
+       @$(QUIET_CMD_ECHO) "  LINK    $$@"
+       $(Q) $(CC) --shared -Xlinker -soname=lib$(1).$(SOLIB_EXT) -o $$@ $$^ $$(LOADLIBES) $$($(1)_LIBS:%=-l%)
+endef
+
+
+
+library-pass-local: $(addprefix $(USER_INCLUDE_DIR)/,$(cmetric_include_HEADERS)) \
+                   $(lib_LIBRARIES:%=$(USER_LIB_DIR)/lib%.a) $(shared_LIBRARIES:%=$(USER_LIB_DIR)/lib%.$(SOLIB_EXT))
+
+binary-pass-local: $(bin_PROGRAMS:%=$(USER_BIN_DIR)/%$(EXE_SUFFIX)) $(utils_PROGRAMS:%=$(USER_UTILS_DIR)/%$(EXE_SUFFIX)) $(test_PROGRAMS:%=$(USER_TESTS_DIR)/%$(EXE_SUFFIX))
+
+# Special rules for CMETRIC generated headers
+
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call COMPILE_c_o_template,\
+               $(SOURCES_DIR)/$($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES),\
+               $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),)))
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call CMETRIC_o_h_template,\
+               $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),\
+               $(addprefix $(USER_INCLUDE_DIR)/,$(cmetrh)))))
+
+GEN_HEADERS+=$(cmetric_include_HEADERS:%=$(USER_INCLUDE_DIR)/%)
+
+GEN_HEADERS+=$(filter %.h,$(USER_IDLS:%.idl=%.h))
+
+# Generate rules for compilation of programs and libraries
+
+$(foreach prog,$(utils_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_UTILS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(test_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_TESTS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(bin_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_BIN_DIR),$(EXE_SUFFIX))))
+
+$(foreach lib,$(lib_LIBRARIES),$(eval $(call LIBRARY_template,$(lib))))
+
+$(foreach lib,$(shared_LIBRARIES),$(eval $(call SOLIB_template,$(lib))))
+
+-include $(USER_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+# Kernel-space rules and templates to compile modules, libraries etc.
+
+ifdef KERN_RULE_TEMPLATES
+
+$(KERN_LIB_DIR)/kernel.mk: $(LINUX_DIR)/.config $(MAKERULES_DIR)/kernelcfg2mk
+       @$(QUIET_CMD_ECHO) "  KCFG2MK $$@"
+       $(Q) $(MAKERULES_DIR)/kernelcfg2mk $(LINUX_DIR) $(KERN_LIB_DIR)
+
+ifeq ($(CONFIG_RTLINUX),y)
+include $(RTL_DIR)/rtl.mk
+
+KERN_CC = $(CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+INCLUDES := -I $(KERN_INCLUDE_DIR) $(INCLUDE) $(rtlinux_INCLUDES) $(kernel_INCLUDES)
+#-DEXPORT_NO_SYMBOLS
+c_o_kern_COMPILE = $(KERN_CC) -idirafter $(kern_GCCLIB_DIR)/include $(INCLUDES)  $(CFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(CXX) $(INCLUDES) $(CXXFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := .o
+KERN_ARCH = $(ARCH)
+KERN_LD = $(LD)
+KERN_AR = $(AR)
+
+else # CONFIG_RTLINUX
+
+include $(KERN_LIB_DIR)/kernel.mk
+
+ifeq ($(LINUX_SRC),)
+LINUX_SRC = $(LINUX_DIR)
+endif
+kernel_INCLUDES += -I $(LINUX_DIR) -idirafter $(LINUX_SRC)/include/linux
+
+ifdef LINUX_CC
+KERN_CC = $(LINUX_CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(LINUX_CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+else
+KERN_CC = echo KERN_CC not defined - compilation skipped
+endif
+c_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+S_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_AFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := $(LINUX_MODULE_EXT)
+KERN_LDFLAGS = $(LINUX_LDFLAGS)
+ifdef LINUX_ARCH
+KERN_ARCH = $(LINUX_ARCH)
+else
+KERN_ARCH = echo KERN_ARCH not defined - skipped
+endif
+ifdef LINUX_LD
+KERN_LD = $(LINUX_LD)
+else
+KERN_LD = echo KERN_LD  not defined - skipped
+endif
+ifneq ($(LINUX_AR),)
+KERN_AR = $(LINUX_AR)
+else
+KERN_AR = $(AR)
+endif
+ifeq ($(LINUX_QUOTE_MODNAME),y)
+KERN_MQ=\"
+KERN_KBUILD_MODNAME=-D"KBUILD_MODNAME=((THIS_MODULE)!=NULL?(THIS_MODULE)->name:NULL)"
+endif
+endif # CONFIG_RTLINUX
+
+KERN_LOADLIBES += -L$(KERN_LIB_DIR) 
+
+KERN_LOADLIBES += $(rtlinux_LOADLIBES:%=-l%)
+KERN_LOADLIBES += $(kernel_LOADLIBES:%=-l%)
+
+
+
+# Check GCC version for kernel part of build
+ifndef kern_CC_MAJOR_VERSION
+kern_CC_MAJOR_VERSION := $(shell $(KERN_CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(kern_CC_MAJOR_VERSION),2)
+kern_CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+kern_CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+ifeq ($(KERN_EXE_SUFFIX),.ko)
+ifeq ($(wildcard $(LINUX_DIR)/scripts/mod/modpost),)
+KERN_MODPOST = $(LINUX_DIR)/scripts/modpost
+else
+KERN_MODPOST = $(LINUX_DIR)/scripts/mod/modpost
+endif
+KERN_MODULES_LINK_DIR = $(KERN_MODPOST_DIR)
+KERN_LINK_SUFFIX = .o
+else
+KERN_MODULES_LINK_DIR = $(KERN_MODULES_DIR)
+KERN_LINK_SUFFIX = $(KERN_EXE_SUFFIX)
+endif
+
+ifeq ($(LINUX_CONFIG_MODVERSIONS),y)
+MODPOST_OPTS += -m
+MODPOST_OPTS += -i $(LINUX_DIR)/Module.symvers
+ifneq ($(LINUX_BUILDHOST),) # this is not correct point, it should look for 2.6.17 kernel
+MODPOST_OPTS += -I $(KERN_LIB_DIR)/Module.symvers
+endif
+MODPOST_OPTS += -o $(KERN_LIB_DIR)/Module.symvers
+endif
+
+ifeq ($(LINUX_CONFIG_DEBUG_SECTION_MISMATCH),y)
+MODPOST_OPTS += -S
+endif
+
+ifeq ($(LINUX_CONFIG_MARKERS),y)
+MODPOST_OPTS += -K $(LINUX_DIR)/Module.markers
+MODPOST_OPTS += -M $(KERN_LIB_DIR)/Module.markers
+endif
+
+ifeq ($(LINUX_KBUILD_MODPOST_WARN),y)
+MODPOST_OPTS += -w
+endif
+
+ifneq ($(LINUX_BUILDHOST),)
+ifneq ($(LINUX_BUILDHOST),$(LINUX_ARCH))
+MODPOST_OPTS += -c
+endif
+endif
+
+define COMPILE_c_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CC [K]  $$@"
+       $(Q) if $$(c_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define COMPILE_cc_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CXX [K] $$@"
+       $(Q) if $$(cc_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define COMPILE_S_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  AS [K]  $$@"
+       $(Q) if $$(S_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define MODULE_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS  += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+# this is hack to build "__this_module" structure for 2.6.x kernels
+# modpost is used for that purpose now
+
+#$(1).mod.c:
+#      echo  "\
+#      #include <linux/version.h>@\
+#      #include <linux/module.h>@\
+#      #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,5))@\
+#      #include <linux/vermagic.h>@\
+#      #include <linux/compiler.h>@\
+#      @\
+#      MODULE_INFO(vermagic, VERMAGIC_STRING);@\
+#      @\
+#      #undef unix@\
+#      struct module __this_module@\
+#      __attribute__((section(\".gnu.linkonce.this_module\"))) = {@\
+#       .name = __stringify(KBUILD_MODNAME),@\
+#       .init = init_module,@\
+#      #ifdef CONFIG_MODULE_UNLOAD@\
+#       .exit = cleanup_module,@\
+#      #endif@\
+#      };@\
+#      #endif@\
+#      " | tr @ \\n >$$@ 
+
+
+#$(eval $(call COMPILE_c_o_kern_template,$(1).mod.c,$(1).mod.o,-DKBUILD_MODNAME=$(1)))
+
+$(2)/$(1)$(KERN_LINK_SUFFIX): $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  LD [K]  $$@"
+       $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) -r $$($(1)_OBJS) -L$$(kern_GCCLIB_DIR) $$($(1)_LIBS:%=-l%) $$(KERN_LOADLIBES) -Map $(KERN_OBJS_DIR)/$(1).mod.map -o $$@
+       @echo "$(2)/$(1)$(KERN_LINK_SUFFIX): \\" >$(KERN_OBJS_DIR)/$(1).mod.d
+       @sed -n -e 's/^LOAD \(.*\)$$$$/  \1  \\/p' $(KERN_OBJS_DIR)/$(1).mod.map  >>$(KERN_OBJS_DIR)/$(1).mod.d
+       @echo >>$(KERN_OBJS_DIR)/$(1).mod.d
+       @if [ "$(KERN_EXE_SUFFIX)" = ".ko" ] ; then \
+         echo $(1) >>$(KERN_MODPOST_DIR)/module-changes ; \
+         echo $(1) >$(KERN_MODPOST_DIR)/$(1).mod.stamp ; \
+       fi
+
+endef
+
+
+
+define LIBRARY_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS  += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+$(KERN_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  AR [K]  $$@"
+       $(Q) $(KERN_AR) rcs $$@ $$^
+endef
+
+
+ifdef LINUX_DIR
+
+kernel-lib-pass-local: $(kernel_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+kernel-mod-pass-local: $(kernel_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+$(foreach module,$(kernel_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(kernel_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+
+ifeq ($(CONFIG_RTLINUX),y)
+
+kernel-mod-pass-local: $(rtlinux_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+kernel-lib-pass-local: $(rtlinux_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+$(foreach module,$(rtlinux_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(rtlinux_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+ifeq ($(KERN_MODPOST_PASS),y)
+
+MODULES_LIST :=        $(wildcard *.mod.stamp)
+MODULES_LIST := $(MODULES_LIST:%.mod.stamp=%)
+
+define MODPOST_kern_template
+$(2) : $(1)$(KERN_LINK_SUFFIX) $(1).mod.c
+       @$(QUIET_CMD_ECHO) "  LD [M]  $$@"
+       $(Q) $$(cc_o_kern_COMPILE) -D"KBUILD_BASENAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+               -D"KBUILD_MODNAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+               -o $(1).mod.o -c $(1).mod.c
+       $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) $(1)$(KERN_LINK_SUFFIX) $(1).mod.o -r -o $$@
+endef
+
+kernel-modpost-versions: $(wildcard $(LINUX_DIR)/Module.symvers)
+       @$(QUIET_CMD_ECHO) "  MODPOST    $(KERN_MODPOST_DIR)"
+       @echo  >$(KERN_MODPOST_DIR)/modpost-running
+       @rm -f $(KERN_MODPOST_DIR)/module-changes
+       $(Q) $(KERN_MODPOST) $(MODPOST_OPTS) $(MODULES_LIST:%=%$(KERN_LINK_SUFFIX))
+
+$(MODULES_LIST:%=%.mod.c) : kernel-modpost-versions
+
+kernel-modpost-pass-local: $(MODULES_LIST:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX))
+       @rm -f $(KERN_MODPOST_DIR)/modpost-running
+
+$(foreach module,$(MODULES_LIST),$(eval $(call MODPOST_kern_template,$(module),$(module:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX)))))
+
+endif
+
+-include $(KERN_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+
+# Kernel requires its own set of configuration header-files
+ifneq ($(kernel_LIBRARIES)$(rtlinux_LIBRARIES)$(kernel_MODULES)$(rtlinux_MODULES)$(kernel_HEADERS)$(rtlinux_HEADERS)$(kernel_HEADERS)$(rtlinux_HEADERS)$(nobase_kernel_HEADERS)$(nobase_rtlinux_HEADERS)$(renamed_kernel_HEADERS)$(renamed_rtlinux_HEADERS),)
+KERN_CONFIG_HEADERS_REQUIRED = y
+endif
+
+$(eval $(call omk_pass_template, kernel-lib-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_LIBRARIES)$(rtlinux_LIBRARIES)))
+$(eval $(call omk_pass_template, kernel-mod-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_MODULES)$(rtlinux_MODULES)))
+
+kernel-modpost-pass:
+       +@if [ -e "$(KERN_MODPOST_DIR)/module-changes" -o -e "$(KERN_MODPOST_DIR)/modpost-running" ] ; \
+       then \
+           $(MAKE) --no-print-directory -C $(KERN_MODPOST_DIR) \
+              -f $(SOURCES_DIR)/Makefile KERN_RULE_TEMPLATES=y KERN_MODPOST_PASS=y $(@:%=%-local) ; \
+       fi
+
+$(eval $(call omk_pass_template, library-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(lib_LIBRARIES)$(shared_LIBRARIES)))
+$(eval $(call omk_pass_template, binary-pass, $(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(bin_PROGRAMS)$(utils_PROGRAMS)$(test_PROGRAMS)))
+
+$(eval $(call omk_pass_template,clean,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,install,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,include-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,always))
+
+check-dir:
+       @$(call mkdir_def,$(USER_BUILD_DIR))
+       @$(call mkdir_def,$(KERN_BUILD_DIR))
+       @$(call mkdir_def,$(USER_INCLUDE_DIR))
+       @$(call mkdir_def,$(KERN_INCLUDE_DIR))
+       @$(call mkdir_def,$(USER_LIB_DIR))
+       @$(call mkdir_def,$(KERN_LIB_DIR))
+       @$(call mkdir_def,$(USER_BIN_DIR))
+       @$(call mkdir_def,$(USER_UTILS_DIR))
+       @$(call mkdir_def,$(USER_TESTS_DIR))
+       @$(call mkdir_def,$(KERN_MODULES_DIR))
+       @$(call mkdir_def,$(KERN_MODPOST_DIR))
+
+install-local:                 # TODO
+
+$(eval $(call include-pass-template,$(USER_INCLUDE_DIR),include))
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),kernel))
+ifeq ($(CONFIG_RTLINUX),y)
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),rtlinux))
+endif
+
+
+ifdef USER_RULE_TEMPLATES
+
+# User-space static libraries and applications object files
+
+USER_SOURCES := $(sort $(USER_SOURCES))
+
+USER_GEN_SOURCES := $(sort $(USER_GEN_SOURCES))
+
+#$(warning USER_SOURCES = $(USER_SOURCES))
+
+$(foreach src,$(filter %.c,$(USER_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+
+$(foreach src,$(filter %.c,$(USER_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.o),)))
+
+# User-space shared libraries object files
+
+SOLIB_SOURCES := $(sort $(SOLIB_SOURCES))
+
+SOLIB_GEN_SOURCES := $(sort $(SOLIB_GEN_SOURCES))
+
+#$(warning SOLIB_SOURCES = $(SOLIB_SOURCES))
+#$(warning SOLIB_GEN_SOURCES = $(SOLIB_GEN_SOURCES))
+
+$(foreach src,$(filter %.c,$(SOLIB_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cc,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cxx,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.S,$(SOLIB_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.c,$(SOLIB_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+# IDL compilation
+
+USER_IDLS := $(sort $(USER_IDLS))
+
+$(foreach src,$(filter %.idl,$(USER_IDLS)),$(eval $(call COMPILE_idl_template,$(SOURCES_DIR)/$(src),$(src:%.idl=%))))
+
+endif
+
+ifdef KERN_RULE_TEMPLATES
+
+KERN_SOURCES := $(sort $(KERN_SOURCES))
+
+#$(warning KERN_SOURCES = $(KERN_SOURCES))
+
+$(foreach src,$(filter %.c,$(KERN_SOURCES)),$(eval $(call COMPILE_c_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+endif
+
+clean-local: clean-custom
+       @echo Cleaning in $(KERN_OBJS_DIR) and $(USER_OBJS_DIR)
+       @rm -f $(KERN_OBJS_DIR)/*.o $(USER_OBJS_DIR)/*.[och] $(USER_OBJS_DIR)/*.lo\
+              $(KERN_OBJS_DIR)/*.d $(USER_OBJS_DIR)/*.d \
+              $(KERN_OBJS_DIR)/*.map $(USER_OBJS_DIR)/*.map \
+              $(KERN_OBJS_DIR)/*.mod.c \
+              $(kernel_MODULES:%=$(KERN_MODPOST_DIR)/%.*) \
+              $(LOCAL_CONFIG_H:%=$(KERN_OBJS_DIR)/%) \
+              $(LOCAL_CONFIG_H:%=$(USER_OBJS_DIR)/%)
+       @if [ -e $(KERN_LIB_DIR)/kernel.mk ] ; then \
+           touch -t 200001010101 $(KERN_LIB_DIR)/kernel.mk ; \
+       fi
+
+include-pass-submakes: extra-rules-subdirs
+
+# We must go to EXTRA_RULES_SUBDIRS beofre going to any other
+# directory, since the executables compiled in EXTRA_RULES_SUBDIRS
+# might be needed there.
+include-pass-this-dir $(foreach subdir,$(SUBDIRS),include-pass-$(subdir)-subdir): extra-rules-subdirs
+
+default: include-pass library-pass binary-pass
+ifndef OMIT_KERNEL_PASSES
+# Also make kernel passes if not disabled
+default: kernel-lib-pass kernel-pass
+endif
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@config_h
+# Syntax: $(call BUILD_CONFIG_H_template,<stamp_dir>,<header_file_path>,<list_of_options_to_export>,<header_barrier>)
+define BUILD_CONFIG_H_template
+
+$(addprefix $(1)/,$(notdir $(addsuffix .stamp,$(2)))) : $(CONFIG_FILES)
+       @$(QUIET_CMD_ECHO) "  CONFGEN $$(@:%.stamp=%)"
+       @if [ ! -d `dirname $(2).tmp` ] ; then \
+               mkdir -p `dirname $(2).tmp` ; fi
+       @echo "/* Automatically generated from */" > "$(2).tmp"
+       @echo "/* config files: $$(^:$(OUTPUT_DIR)/%=%) */" >> "$(2).tmp"
+       $(if $(DOXYGEN),@echo "/** @file */" >> "$(2).tmp")
+       @echo "#ifndef $(4)" >> "$(2).tmp"
+       @echo "#define $(4)" >> "$(2).tmp"
+       @( $(foreach x, $(shell echo '$($(3))' | tr 'x\t ' 'x\n\n' | sed -e 's/^\([^ =]*\)\(=[^ ]\+\|\)$$/\1/' ), \
+               echo '$(x).$($(x))' ; ) echo ; ) | \
+               sed -e '/^[^.]*\.n$$$$/d' -e '/^[^.]*\.$$$$/d' -e 's/^\([^.]*\)\.[ym]$$$$/\1.1/' | \
+               sed -n -e 's/^\([^.]*\)\.\(.*\)$$$$/#define \1 \2/p' \
+                 >> "$(2).tmp"
+       @echo "#endif /*$(4)*/" >> "$(2).tmp"
+       @touch "$$@"
+       @if cmp --quiet "$(2).tmp" "$(2)" ; then rm "$(2).tmp"; \
+       else mv "$(2).tmp" "$(2)" ; \
+       echo "Updated configuration $(2)" ; fi
+
+endef
+
+ifdef LOCAL_CONFIG_H
+
+# This must be declared after the default cflags are assigned!
+# Override is used to override command line assignemnt.
+override CFLAGS += -I $(USER_OBJS_DIR)
+override kernel_INCLUDES += -I $(KERN_OBJS_DIR)
+$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(USER_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+
+endif
+
+# Special rules for configuration exported headers
+
+#FIXME: The directory for headers should not be specified here.
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(addprefix $(USER_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+config_h_stamp_files = $(addprefix $(USER_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(config_h_stamp_files)
+
+ifneq ($(KERN_CONFIG_HEADERS_REQUIRED),)
+
+ifdef LOCAL_CONFIG_H
+$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(KERN_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+endif
+
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(addprefix $(KERN_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+kern_config_h_stamp_files = $(addprefix $(KERN_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(kern_config_h_stamp_files)
+
+endif
+
+clean-local: clean-local-config-h
+
+clean-local-config-h:
+       @$(foreach confh,$(config_h_stamp_files) $(kern_config_h_stamp_files),\
+           if [ -e $(confh) ] ; then rm $(confh) ; fi ; \
+       )
+
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@qt
+ifneq ($(QT_SUBDIRS),)
+
+.PHONY: qt-subpass clean-qt distclean-qt
+
+# Usage: $(call qt_makefile_template,<qt-subdir>)
+define qt_makefile_template
+$(SOURCES_DIR)/$(1)/Makefile: $(wildcard $(SOURCES_DIR)/$(1)/*.pro)
+       cd $(SOURCES_DIR)/$(1); $(QTDIR:%=%/bin/)qmake TOP_DIR=$(OUTPUT_DIR) \
+            RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) $(QTDIR:%=QTDIR=%) CC=$(CC) \
+            CXX=$(CXX) LIBS+="-L$(USER_LIB_DIR)" INCLUDEPATH+="$(USER_INCLUDE_DIR)"
+endef
+$(foreach dir,$(QT_SUBDIRS), $(eval $(call qt_makefile_template,$(dir))))
+
+qt-subpass: $(foreach dir,$(QT_SUBDIRS), $(SOURCES_DIR)/$(dir)/Makefile)
+       $(foreach dir,$(QT_SUBDIRS),\
+               $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+               -f $(SOURCES_DIR)/$(dir)/Makefile || exit 1 ;)
+
+# Hook to binary pass
+binary-pass-submakes: qt-subpass
+
+# Hook to clean pass
+clean-local: clean-qt
+clean-qt:
+       +@$(foreach dir, $(QT_SUBDIRS), \
+               $(if $(wildcard $(SOURCES_DIR)/$(dir)/Makefile), \
+               @$(QUIET_CMD_ECHO) "  CLEAN   $(dir)"; \
+               $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+               -f $(SOURCES_DIR)/$(dir)/Makefile clean|| exit 1 ;))
+
+
+# Hook to distclean
+distclean: distclean-qt
+
+# TODO: Add distclean-qt-pass to handle QT_SUBDIRS in the whole
+# tree. This way we only distclean toplevel subdirs.
+distclean-qt:
+       +@$(foreach dir, $(QT_SUBDIRS), \
+               $(if $(wildcard $(SOURCES_DIR)/$(dir)/Makefile), \
+               @$(QUIET_CMD_ECHO) "  DISTCLEAN $(dir)"; \
+               $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+               -f $(SOURCES_DIR)/$(dir)/Makefile distclean|| exit 1 ;))
+endif
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@sources-list
+# Rules that creates the list of files which are used during
+# compilation. The list reflects conditional compilation depending on
+# config.omk and other variables.
+
+SOURCES_LIST_FN=sources.txt
+ifndef SOURCES_LIST
+SOURCES_LIST_DIR:=$(RELATIVE_DIR)
+SOURCES_LIST:=$(OUTPUT_DIR)/$(SOURCES_LIST_DIR)/$(SOURCES_LIST_FN)
+SOURCES_LIST_D := $(LOCAL_BUILD_DIR)/$(SOURCES_LIST_FN).d
+export SOURCES_LIST SOURCES_LIST_DIR SOURCES_LIST_D
+endif
+
+ifeq ($(MAKECMDGOALS),sources-list)
+NEED_SOURCES_LIST=y
+endif
+ifeq ($(MAKECMDGOALS),TAGS)
+NEED_SOURCES_LIST=y
+endif
+ifeq ($(MAKECMDGOALS),tags)
+NEED_SOURCES_LIST=y
+endif
+
+ifeq ($(NEED_SOURCES_LIST),y) # avoid execution of find command bellow if it is not useful
+.PHONY: sources-list
+sources-list: $(SOURCES_LIST)
+
+$(SOURCES_LIST): $(CONFIG_FILES) $(shell find -name $(MAKEFILE_OMK))
+       @$(call mkdir_def,$(dir $(SOURCES_LIST_D)))
+       @echo -n "" > "$(SOURCES_LIST).tmp"
+       @echo -n "" > "$(SOURCES_LIST_D).tmp"
+       @$(MAKE) --no-print-directory sources-list-pass
+       @echo "# Automatically generated list of files in '$(RELATIVE_DIR)' that are used during OMK compilation" > "$(SOURCES_LIST).tmp2"
+       @cat "$(SOURCES_LIST).tmp"|sort|uniq >> "$(SOURCES_LIST).tmp2"
+       @rm "$(SOURCES_LIST).tmp"
+       @mv "$(SOURCES_LIST).tmp2" "$(SOURCES_LIST)"
+       @echo "$(SOURCES_LIST): \\" > "$(SOURCES_LIST_D).tmp2"
+       @cat "$(SOURCES_LIST_D).tmp"|grep -v "$(SOURCES_LIST_D).tmp"|sort|uniq|\
+               sed -e 's/$$/\\/' >> "$(SOURCES_LIST_D).tmp2"
+       @rm "$(SOURCES_LIST_D).tmp"
+       @mv "$(SOURCES_LIST_D).tmp2" "$(SOURCES_LIST_D)"
+endif
+
+$(eval $(call omk_pass_template,sources-list-pass,$$(LOCAL_BUILD_DIR),,always))
+
+sources-list-pass-local:
+       @$(foreach m,$(MAKEFILE_LIST),echo '  $(m)' >> "$(SOURCES_LIST_D).tmp";)
+       @$(foreach h,$(include_HEADERS) $(nobase_include_HEADERS) $(kernel_HEADERS),\
+         echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(h)" >> "$(SOURCES_LIST).tmp";)
+       @$(foreach ch,$(config_include_HEADERS), \
+         echo "$(USER_INCLUDE_DIR:$(OUTPUT_DIR)/$(addsuffix /,$(SOURCES_LIST_DIR))%=%)/$(ch)" >> "$(SOURCES_LIST).tmp";)
+       @$(foreach h,$(renamed_include_HEADERS),echo '$(h)'|sed -e 's|\(.*\)->.*|$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))\1|' >> "$(SOURCES_LIST).tmp";)
+       @$(foreach bin,$(lib_LIBRARIES) $(shared_LIBRARIES) $(bin_PROGRAMS) $(test_PROGRAMS) $(utils_PROGRAMS) \
+         $(kernel_LIBRARIES) $(rtlinux_LIBRARIES) $(kernel_MODULES),\
+         $(foreach src,$(filter-out %.o,$($(bin)_SOURCES)),echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(src)" >> "$(SOURCES_LIST).tmp";))
+
+############ TAGS ###########
+
+ifeq ($(MAKECMDGOALS),TAGS)
+ETAGS=etags
+TAGS_CMD = $(ETAGS)
+TAGS: $(SOURCES_LIST)
+       @$(MAKE) --no-print-directory do-tags
+endif
+ifeq ($(MAKECMDGOALS),tags) 
+CTAGS=ctags -N
+TAGS_CMD = $(CTAGS)
+tags: $(SOURCES_LIST)
+       @$(MAKE) --no-print-directory do-tags
+endif
+export TAGS_CMD
+
+ifeq ($(MAKECMDGOALS),do-tags)
+.PHONY: do-tags
+do-tags: $(shell sed -e '/^\#/d' $(SOURCES_LIST))
+       @$(QUIET_CMD_ECHO) "  TAGS    $(SOURCES_LIST_FN)"
+       $(Q)$(TAGS_CMD) $^
+endif
+
+############ CSCOPE ###########
+
+cscope: $(SOURCES_LIST)
+       @$(QUIET_CMD_ECHO) "  CSCOPE  < $(SOURCES_LIST_FN)"
+       $(Q)sed -e '/^#/d' $(SOURCES_LIST)|cscope -b -i-
+#FIXME: see doc to -i in cscope(1)
+
+# Local Variables:
+# mode:makefile
+# End:
diff --git a/build/marte/config.target b/build/marte/config.target
new file mode 100644 (file)
index 0000000..771e7f1
--- /dev/null
@@ -0,0 +1,54 @@
+# -*- makefile -*-
+# Config file for compilation by OMK for Marte OS target
+
+# You can override this variable in config.omk
+MARTE_PATH=$(firstword $(wildcard $(HOME)/frescor/marte/ $(HOME)/marte/ /usr/src/marte))
+
+export PLATFORM=MARTE_OS
+
+# Create symbolic links to headers instead of copying them. Useful
+# during development.
+LN_HEADERS=y
+
+# We do not want to overwrite original FRESCOR Makefiles
+USE_LEAF_MAKEFILES=n
+
+########################################
+# Setting of compiler
+########################################
+
+# This doesn't work with MARTE OS 1.7 since mgcc script eats multiple
+# -M options. Current version of mgcc works correctly.
+CC=$(MARTE_PATH)/utils/mgcc
+CFLAGS=-Wall -g  -O1  -Wuninitialized -D$(PLATFORM)
+
+ifneq ($(V),2)
+export MGCC_QUIET=y
+endif
+
+# # Instead, with MARTE OS 1.7, we call normal gcc with parameters which mgcc adds
+
+# # List of variables to import from Marte's global.pl
+# MARTE_VARS = MPATH GNAT_PATH ARCH_LD_OPTS CRTI_0 CRTN_O INCLUDES LIBS        \
+#           LIBS_PATH ARCH_GCC_OPTS WRAPPER_MAIN_C_O                   \
+#           WRAPPER_MAIN_CPP_O _EXIT_O
+
+# # Acquire Marte configuration and store it in marte.mk
+# $(MAKERULES_DIR)/marte.mk: $(MARTE_PATH)/utils/globals.pl
+#      @$(QUIET_CMD_ECHO) "  CREATE  marte.mk"
+#      $(Q)perl -e 'require "$(MARTE_PATH)/utils/globals.pl"; foreach (qw/$(MARTE_VARS)/) {print "$$_=$${$$_}\n";}' > $@.tmp
+#      $(Q)mv $@.tmp $@
+
+# # Import Marte configuration as make variables
+# -include $(MAKERULES_DIR)/marte.mk
+
+# # Use the compiler configured for Marte
+# CC=$(GNAT_PATH)/../../../../bin/gcc
+
+# distclean: distclean-marte.mk
+# distclean-marte.mk:
+#      @$(QUIET_CMD_ECHO) "  RM      marte.mk"
+#      $(Q)rm -f $(MAKERULES_DIR)/marte.mk
+
+# CFLAGS=$(ARCH_GCC_OPTS) -Wall -Wuninitialized -g -gstabs+ -O1 -D$(PLATFORM)
+# LDFLAGS=$(ARCH_LD_OPTS) $(CRTI_0) $(WRAPPER_MAIN_C_O) $(_EXIT_O) $(LIBS_PATH) $(LIBS) $(CRTN_O)
diff --git a/build/marte/create-links b/build/marte/create-links
new file mode 100755 (executable)
index 0000000..9a0fc93
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# Usage: ./create-links [path/to/frescor/root]
+#
+# path/to/frescor/root defaults to ../..
+
+LINKS="
+dtm
+fna
+fosa
+frsh
+fsa
+utils
+"
+
+FRESCOR_SRC=${1:-../..}
+
+for link in $LINKS; do
+       ln -s $FRESCOR_SRC/$link .
+done
+
diff --git a/doc/RelNotes-0.1.1.txt b/doc/RelNotes-0.1.1.txt
new file mode 100644 (file)
index 0000000..d4fd8aa
--- /dev/null
@@ -0,0 +1,12 @@
+FRSH/FORB 0.1.1
+===============
+
+This is mostly a bug-fix release. The main differences from version
+0.1 are:
+
+- Added frsh_get_local_cpu_id() which returns either compiled in local
+  CPU ID or, if set, the value of FRSH_CPU_ID environment variable.
+  This function is used by CPU resource managers/allocators and should
+  also be used by applications.
+- A few bugs fixed in BFQ, Cgroup and FWP resource managers.
+- Up-to-date Makefile.rules
diff --git a/doc/RelNotes-0.1.txt b/doc/RelNotes-0.1.txt
new file mode 100644 (file)
index 0000000..ab05abe
--- /dev/null
@@ -0,0 +1,26 @@
+FRSH/FORB 0.1
+=============
+
+This is the first official release of FRSH/FORB resource reservation
+framework for real-time and distributed applications.
+
+The main differences from the version available at the end of FRESCOR
+project are the following:
+
+- FRSH WLAN Protocol (FWP) was reworked quite a lot. 
+  * It contains new version of VRES budgeting which handles correctly
+    all corner cases. 
+  * FWP overhead was decreased significantly by allowing sending of
+    packets directly from application threads instead of VRES threads,
+    which are now used only if the budget is exhausted. 
+  * Synchronous send operation was implemented.
+  * New application fwp-timing was developed to measure communication
+    delays and packet looses. It showed that the previously mentioned
+    changes improved FWP parameters.
+- FRSH API was slightly changed to remove problematic things.
+  See commit b5508fb2d706b33491fbde62a675432300b43542.
+- Improved logging. Every log message is now prefixed by the name of
+  the process.
+- Several bugs were fixed:
+  * Race condition in registration of allocators.
+  * Incorrect block id in disk BFQ resource
diff --git a/scripts/reselase.sh b/scripts/reselase.sh
new file mode 100755 (executable)
index 0000000..480cda7
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+cd ./$(git rev-parse --show-cdup)
+
+if ! git submodule foreach --quiet 'git diff-files --quiet && git diff-index --quiet HEAD'
+then
+    echo >&2 "Submodules are not clean"
+    exit 1
+fi
+
+if ! git diff-files --quiet || ! git diff-index --quiet HEAD
+then
+    echo >&2 "The work tree is not clean"
+    exit 1
+fi
+
+NAME=${NAME:-frsh-forb}
+VERSION=`git describe|sed -e s/^v//`
+
+( git submodule foreach --quiet 'git ls-files|sed -e "s|^|$path/|"'; \
+    git ls-files -s|grep -v ^16|awk '{print $4;}' ) \
+    | grep -v '\(.gitignore\|.gitmodules\)' | \
+tar -czf ${NAME}-${VERSION}.tar.gz --files-from - --transform "s|^\([^\.].*\)|${NAME}-${VERSION}/\1|"
similarity index 100%
rename from .gitignore
rename to src/forb/.gitignore
similarity index 100%
rename from COPYING
rename to src/forb/COPYING
similarity index 100%
rename from Doxyfile
rename to src/forb/Doxyfile
similarity index 100%
rename from Makefile.omk
rename to src/forb/Makefile.omk
diff --git a/src/forb/README b/src/forb/README
new file mode 100644 (file)
index 0000000..f6969c0
--- /dev/null
@@ -0,0 +1,22 @@
+Compilation
+===========
+
+1. Download FRESCOR SVN repositories fosa and omk-build
+
+2. Download ulut (from
+   http://sourceforge.net/project/showfiles.php?group_id=118937&package_id=130840)
+
+3. Create symbolic links to forb, fosa and ulut sources inside
+   omk-build/aquosa:
+
+   cd omk-build/aquosa
+   ln -s some-path/fosa .
+   ln -s some-path/ulut .
+   ln -s path-to-this-directory/forb .
+
+3. Configure the sources:
+       make default-config
+
+5. Compile it:
+       make    
+       
similarity index 100%
rename from TODO
rename to src/forb/TODO
similarity index 100%
rename from doc/forb.vpp
rename to src/forb/doc/forb.vpp
similarity index 100%
rename from forb-idl/config.h
rename to src/forb/forb-idl/config.h
similarity index 100%
rename from tests-idl/Makefile
rename to src/forb/src/Makefile
similarity index 100%
rename from src/Makefile.omk
rename to src/forb/src/Makefile.omk
similarity index 100%
rename from src/basic_types.h
rename to src/forb/src/basic_types.h
similarity index 100%
rename from src/cdr.c
rename to src/forb/src/cdr.c
similarity index 100%
rename from src/cdr.h
rename to src/forb/src/cdr.h
similarity index 100%
rename from src/cdr_codec.h
rename to src/forb/src/cdr_codec.h
similarity index 100%
rename from src/daemon.c
rename to src/forb/src/daemon.c
similarity index 100%
rename from src/discovery.c
rename to src/forb/src/discovery.c
similarity index 100%
rename from src/discovery.h
rename to src/forb/src/discovery.h
similarity index 100%
rename from src/exec_req.c
rename to src/forb/src/exec_req.c
similarity index 100%
rename from src/exec_req.h
rename to src/forb/src/exec_req.h
similarity index 100%
rename from src/executor.c
rename to src/forb/src/executor.c
similarity index 100%
rename from src/executor.h
rename to src/forb/src/executor.h
similarity index 100%
rename from src/forb-idl.idl
rename to src/forb/src/forb-idl.idl
similarity index 100%
rename from src/forb.c
rename to src/forb/src/forb.c
similarity index 100%
rename from src/forb.h
rename to src/forb/src/forb.h
similarity index 100%
rename from src/forb_endian.h
rename to src/forb/src/forb_endian.h
similarity index 100%
rename from src/forb_utils.h
rename to src/forb/src/forb_utils.h
similarity index 100%
rename from src/iop-idl.idl
rename to src/forb/src/iop-idl.idl
similarity index 100%
rename from src/iop.c
rename to src/forb/src/iop.c
similarity index 100%
rename from src/iop.h
rename to src/forb/src/iop.h
similarity index 100%
rename from src/object.c
rename to src/forb/src/object.c
similarity index 100%
rename from src/object.h
rename to src/forb/src/object.h
similarity index 100%
rename from src/object_type.h
rename to src/forb/src/object_type.h
similarity index 100%
rename from src/peer.c
rename to src/forb/src/peer.c
similarity index 100%
rename from src/peer.h
rename to src/forb/src/peer.h
similarity index 100%
rename from src/port.c
rename to src/forb/src/port.c
similarity index 100%
rename from src/port.h
rename to src/forb/src/port.h
similarity index 100%
rename from src/proto.c
rename to src/forb/src/proto.c
similarity index 100%
rename from src/proto.h
rename to src/forb/src/proto.h
similarity index 100%
rename from src/proto_inet.c
rename to src/forb/src/proto_inet.c
similarity index 100%
rename from src/proto_inet.h
rename to src/forb/src/proto_inet.h
similarity index 100%
rename from src/proto_unix.c
rename to src/forb/src/proto_unix.c
similarity index 100%
rename from src/proto_unix.h
rename to src/forb/src/proto_unix.h
similarity index 100%
rename from src/refcnt.c
rename to src/forb/src/refcnt.c
similarity index 100%
rename from src/refcnt.h
rename to src/forb/src/refcnt.h
similarity index 100%
rename from src/regref.c
rename to src/forb/src/regref.c
similarity index 100%
rename from src/regref.h
rename to src/forb/src/regref.h
similarity index 100%
rename from src/request.c
rename to src/forb/src/request.c
similarity index 100%
rename from src/request.h
rename to src/forb/src/request.h
similarity index 100%
rename from src/server_id.h
rename to src/forb/src/server_id.h
similarity index 100%
rename from src/sha1.c
rename to src/forb/src/sha1.c
similarity index 100%
rename from src/sha1.h
rename to src/forb/src/sha1.h
similarity index 100%
rename from src/syncobj.c
rename to src/forb/src/syncobj.c
similarity index 100%
rename from src/syncobj.h
rename to src/forb/src/syncobj.h
diff --git a/src/forb/src/tests/Makefile b/src/forb/src/tests/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/forb/src/tests/object_to_string/Makefile b/src/forb/src/tests/object_to_string/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/forb/src/tests/objref/Makefile b/src/forb/src/tests/objref/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
similarity index 100%
rename from src/types.idl
rename to src/forb/src/types.idl
similarity index 100%
rename from src/uuid.c
rename to src/forb/src/uuid.c
similarity index 100%
rename from src/uuid.h
rename to src/forb/src/uuid.h
diff --git a/src/forb/tests-idl/Makefile b/src/forb/tests-idl/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/frsh-forb.el b/src/frsh-forb.el
new file mode 100644 (file)
index 0000000..12bf5ed
--- /dev/null
@@ -0,0 +1,65 @@
+;;; frsh-forb.el --- Helper functions for editing FRSH/FORB sources
+
+;; Copyright (C) 2010  Michal Sojka
+
+;; Author: Michal Sojka <sojkam1@fel.cvut.cz>
+;; Keywords: c, files, convenience
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; 
+
+;;; Code:
+
+(defun update-fres-error-c ()
+  "When called from fres_error.h it updates fres_error.c to match
+the list if defined errors"
+  (save-excursion
+    (beginning-of-buffer)
+    (let* ((beg (progn
+                 (re-search-forward "^enum fres_error \{")
+                 (beginning-of-line 2)
+                 (point)))
+          (end (progn
+                 (search-forward "}")
+                 (beginning-of-line)
+                 (point))))
+      (let ((errors))
+       (save-restriction
+         (narrow-to-region beg end)
+         (goto-char (point-min))
+         (while (re-search-forward "^[[:space:]]*FRES_ERR_" nil t)
+           (push (current-word) errors)))
+       (save-current-buffer
+         (set-buffer (find-file-noselect "fres_error.c"))
+         (beginning-of-buffer)
+         (search-forward "switch (e) {")
+         (kill-region (point) (save-excursion (search-forward "}") (backward-char) (point)))
+         (insert "\n")
+
+         (dolist (e errors)
+           (insert "\n")
+           (indent-according-to-mode)
+           (previous-line)
+           (insert (concat "MSG(" (replace-regexp-in-string "^FRES_ERR_" "" e) ");"))
+           (indent-according-to-mode)
+           (beginning-of-line)))))
+    (message "fres_error.c updated")))
+
+
+
+(provide 'frsh-forb)
+;;; frsh-forb.el ends here
diff --git a/src/update-frescor-svn b/src/update-frescor-svn
new file mode 100755 (executable)
index 0000000..bb2167f
--- /dev/null
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# Script to track FRESCOR SVN repositories. We do this in order not to
+# diverge to much from the original code so that it can be easily
+# joined in future if it will be necessary.
+
+set -e
+
+update() {
+    local dir=$1
+    local svnrepo=$2
+    cd $dir
+    echo "Updating $dir"
+    if ! git config --get  svn-remote.svn.url > /dev/null; then
+       git svn init $svnrepo
+    fi
+
+    git svn fetch
+    local gitbranch=`git show-ref --verify --hash refs/heads/frescor-svn`
+    local svnbranch=`git show-ref --verify --hash refs/remotes/git-svn`
+    
+    if [ -z "$gitbranch" ]; then
+       echo "  Creating frescor-svn branch"
+       git branch frescor-svn git-svn
+    else
+       if [ "$gitbranch" != "$svnbranch" ]; then
+           echo "  Merging SVN to branch frescor-svn"
+           git merge git-svn
+           git checkout master
+       else
+           echo "  Already up-to-date"
+       fi
+    fi
+    cd ..
+}
+
+update frsh-include http://www.frescor.org/private/svn/frescor/frsh/trunk/include
+update fosa        http://www.frescor.org/private/svn/frescor/fosa/trunk
+update fna         http://www.frescor.org/private/svn/frescor/fna/trunk
diff --git a/src/update-to-git-head b/src/update-to-git-head
new file mode 100755 (executable)
index 0000000..e19452b
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+find -type d -name .git -print \
+       -execdir git checkout master \; \
+       -execdir git pull \;
diff --git a/src/wvtest.sh b/src/wvtest.sh
new file mode 100755 (executable)
index 0000000..30574cb
--- /dev/null
@@ -0,0 +1,154 @@
+#
+# Include this file in your shell script by using:
+#         #!/bin/sh
+#         . ./wvtest.sh
+#
+
+# we don't quote $TEXT in case it contains newlines; newlines
+# aren't allowed in test output.  However, we set -f so that
+# at least shell glob characters aren't processed.
+_wvtextclean()
+{
+       ( set -f; echo $* )
+}
+
+
+if [ -n "$BASH_VERSION" ]; then
+       _wvfind_caller()
+       {
+               LVL=$1
+               WVCALLER_FILE=${BASH_SOURCE[2]}
+               WVCALLER_LINE=${BASH_LINENO[1]}
+       }
+else
+       _wvfind_caller()
+       {
+               LVL=$1
+               WVCALLER_FILE="unknown"
+               WVCALLER_LINE=0
+       }
+fi
+
+
+_wvcheck()
+{
+       CODE="$1"
+       TEXT=$(_wvtextclean "$2")
+       OK=ok
+       if [ "$CODE" -ne 0 ]; then
+               OK=FAILED
+       fi
+       echo "! $WVCALLER_FILE:$WVCALLER_LINE  $TEXT  $OK" >&2
+       if [ "$CODE" -ne 0 ]; then
+               exit $CODE
+       else
+               return 0
+       fi
+}
+
+
+WVPASS()
+{
+       TEXT="$*"
+       
+       _wvfind_caller
+       if "$@"; then
+               _wvcheck 0 "$TEXT"
+               return 0
+       else
+               _wvcheck 1 "$TEXT"
+               # NOTREACHED
+               return 1
+       fi
+}
+
+
+WVFAIL()
+{
+       TEXT="$*"
+       
+       _wvfind_caller
+       if "$@"; then
+               _wvcheck 1 "NOT($TEXT)"
+               # NOTREACHED
+               return 1
+       else
+               _wvcheck 0 "NOT($TEXT)"
+               return 0
+       fi
+}
+
+
+_wvgetrv()
+{
+       ( "$@" >&2 )
+       echo -n $?
+}
+
+
+WVPASSEQ()
+{
+       _wvfind_caller
+       _wvcheck $(_wvgetrv [ "$#" -eq 2 ]) "exactly 2 arguments"
+       echo "Comparing:" >&2
+       echo "$1" >&2
+       echo "--" >&2
+       echo "$2" >&2
+       _wvcheck $(_wvgetrv [ "$1" = "$2" ]) "'$1' = '$2'"
+}
+
+
+WVPASSNE()
+{
+       _wvfind_caller
+       _wvcheck $(_wvgetrv [ "$#" -eq 2 ]) "exactly 2 arguments"
+       echo "Comparing:" >&2
+       echo "$1" >&2
+       echo "--" >&2
+       echo "$2" >&2
+       _wvcheck $(_wvgetrv [ "$1" != "$2" ]) "'$1' != '$2'"
+}
+
+
+WVPASSRC()
+{
+       RC=$?
+       _wvfind_caller
+       _wvcheck $(_wvgetrv [ $RC -eq 0 ]) "return code($RC) == 0"
+}
+
+
+WVFAILRC()
+{
+       RC=$?
+       _wvfind_caller
+       _wvcheck $(_wvgetrv [ $RC -ne 0 ]) "return code($RC) != 0"
+}
+
+
+WVSTART()
+{
+       echo >&2
+       _wvfind_caller
+       echo "Testing \"$*\" in $WVCALLER_FILE:" >&2
+}
+
+
+root=$(
+old_pwd=""
+while [ ! -e Makefile.rules ]; do
+       if [ "$old_pwd" = `pwd`  ]; then 
+              echo "Makefile.rules has not been found in this or parent directory" >&2; exit 1; 
+       else
+              old_pwd=`pwd`; 
+              cd -L .. 2>/dev/null; 
+       fi; 
+done; 
+pwd
+)
+
+if [ "$root" ]; then
+    PATH="$root/_compiled/bin:$root/_compiled/bin-tests:$PATH"
+else
+    exit 1
+fi