aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-08-26 14:39:08 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-08-26 14:39:08 +0200
commitf00465eecdcf50965e8ca455527a49759bfcddbd (patch)
tree6a02a5938cc42df55c4335701ebde778d0351803
parentae283997b95c18181091e530ba554624cd93a0e2 (diff)
Add meta-build subsystem
Meta-build is used to create (or, more precisely, maintain) other build systems. The idea is to create templates for other build systems (automake, VC++ projects) which are then processed by meta-build to fill in the details such as files to compile, etc. The template system is built on top of GNU m4. Currently supported build systems are autoconf, automake, VC++ 9, and VC++ 10.
-rwxr-xr-xbuild/meta/autoconf84
-rw-r--r--build/meta/autoconf-functions.make22
-rw-r--r--build/meta/autoconf.m419
-rw-r--r--build/meta/autoconf.make6
-rwxr-xr-xbuild/meta/automake64
-rw-r--r--build/meta/automake-functions.make22
-rw-r--r--build/meta/automake.m419
-rw-r--r--build/meta/automake.make6
-rw-r--r--build/meta/common.m476
-rwxr-xr-xbuild/meta/vc10proj78
-rw-r--r--build/meta/vc10proj-functions.make21
-rw-r--r--build/meta/vc10proj.m4109
-rw-r--r--build/meta/vc10proj.make6
-rwxr-xr-xbuild/meta/vc9proj75
-rw-r--r--build/meta/vc9proj-functions.make21
-rw-r--r--build/meta/vc9proj.m477
-rw-r--r--build/meta/vc9proj.make6
17 files changed, 711 insertions, 0 deletions
diff --git a/build/meta/autoconf b/build/meta/autoconf
new file mode 100755
index 0000000..933faf8
--- /dev/null
+++ b/build/meta/autoconf
@@ -0,0 +1,84 @@
+#! /usr/bin/env bash
+
+# file : build/meta/autoconf
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+# Process autconf configure.ac templates.
+#
+# Options:
+#
+# -b <base-dir>
+# -o <output-file>
+#
+# Arguments:
+#
+# <template-file>
+#
+trap 'exit 1' ERR
+
+function error ()
+{
+ echo "$*" 1>&2
+}
+
+base=
+output=
+
+while [ $# -gt 0 ]; do
+ case $1 in
+ -b)
+ base=$2
+ shift 2
+ ;;
+ -o)
+ output=$2
+ shift 2
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+input=$1
+
+if [ "$input" = "" ]; then
+ error "no input file"
+ exit 1
+fi
+
+if [ "$base" = "" ]; then
+ error "no base directory"
+ exit 1
+fi
+
+if [ "$output" = "" ]; then
+ error "no output file"
+ exit 1
+fi
+
+m4=m4
+
+# Assume this script is never found via PATH.
+#
+meta=`dirname $0`
+
+build="$meta/.."
+install=$build/install/install
+
+# Find all the configuration files.
+#
+files=`find $base -name 'Makefile.am' -o -name '*.in' -a ! -name '*.h.in' | \
+sed -e "s%^$base/%%" | \
+sed -e 's%\.\(am\|in\)$%%' | \
+sort -u`
+
+export config_files=$files
+
+# Make sure the output directory exist.
+#
+$install -d -m 755 `dirname $output`
+
+exec $m4 -P -D__meta_base__=$meta $meta/autoconf.m4 $input >$output
diff --git a/build/meta/autoconf-functions.make b/build/meta/autoconf-functions.make
new file mode 100644
index 0000000..1f64f8d
--- /dev/null
+++ b/build/meta/autoconf-functions.make
@@ -0,0 +1,22 @@
+# file : build/meta/autoconf-functions.make
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+# Process autoconf template and write output to $(dist_prefix)/<path>.
+# Where path is computed as difference between src_base and src_root.
+#
+# Arguments:
+#
+# $1 - optional template, default is $(src_base)/configure.ac
+#
+$(out_base)/%: meta-autoconf = \
+$(call meta-autoconf-body,$(if $1,$1,$(src_base)/configure.ac),$(subst \
+$(src_root),,$(src_base)))
+
+# $1 - template
+# $2 - difference between src_base and src_root with leading '\'
+#
+$(out_base)/%: meta-autoconf-body = \
+$(call message,meta $(dist_prefix)$2/$(notdir $1),$(bld_root)/meta/autoconf \
+-b $(dist_prefix)$2 -o $(dist_prefix)$2/$(notdir $1) $1)
diff --git a/build/meta/autoconf.m4 b/build/meta/autoconf.m4
new file mode 100644
index 0000000..82d0696
--- /dev/null
+++ b/build/meta/autoconf.m4
@@ -0,0 +1,19 @@
+m4_divert(-1)
+# file : build/meta/autoconf.m4
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+m4_include(__meta_base__`/common.m4')
+
+m4_define(`__path_impl__', `__env_impl__(`$1')')
+m4_define(`__path__', `m4_equote()__path_impl__(`$1')`'m4_dquote()')
+
+m4_define(`__file_impl__', `__env_impl__(`$1')')
+m4_define(`__file__', `m4_equote()__file_impl__(`$1')`'m4_dquote()')
+
+# Disable quoting.
+#
+m4_changequote('')
+
+m4_divert(0)dnl
diff --git a/build/meta/autoconf.make b/build/meta/autoconf.make
new file mode 100644
index 0000000..c62cd42
--- /dev/null
+++ b/build/meta/autoconf.make
@@ -0,0 +1,6 @@
+# file : build/meta/autoconf.make
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(call include-once,$(bld_root)/meta/autoconf-functions.make,$(out_base))
diff --git a/build/meta/automake b/build/meta/automake
new file mode 100755
index 0000000..ef5db66
--- /dev/null
+++ b/build/meta/automake
@@ -0,0 +1,64 @@
+#! /usr/bin/env bash
+
+# file : build/meta/automake
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+# Process automake Makefile.am templates.
+#
+# Options:
+#
+# -o <output-file>
+#
+# Arguments:
+#
+# <template-file>
+#
+trap 'exit 1' ERR
+
+function error ()
+{
+ echo "$*" 1>&2
+}
+
+output=
+
+while [ $# -gt 0 ]; do
+ case $1 in
+ -o)
+ output=$2
+ shift 2
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+input=$1
+
+if [ "$input" = "" ]; then
+ error "no input file"
+ exit 1
+fi
+
+if [ "$output" = "" ]; then
+ error "no output file"
+ exit 1
+fi
+
+m4=m4
+
+# Assume this script is never found via PATH.
+#
+meta=`dirname $0`
+
+build="$meta/.."
+install=$build/install/install
+
+# Make sure the output directory exist.
+#
+$install -d -m 755 `dirname $output`
+
+exec $m4 -P -D__meta_base__=$meta $meta/automake.m4 $input >$output
diff --git a/build/meta/automake-functions.make b/build/meta/automake-functions.make
new file mode 100644
index 0000000..114779f
--- /dev/null
+++ b/build/meta/automake-functions.make
@@ -0,0 +1,22 @@
+# file : build/meta/automake-functions.make
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+# Process automake template and write output to $(dist_prefix)/<path>.
+# Where path is computed as difference between src_base and src_root.
+#
+# Arguments:
+#
+# $1 - optional template, default is $(src_base)/Makefile.am
+#
+$(out_base)/%: meta-automake = \
+$(call meta-automake-body,$(if $1,$1,$(src_base)/Makefile.am),$(subst \
+$(src_root),,$(src_base)))
+
+# $1 - template
+# $2 - difference between src_base and src_root with leading '\'
+#
+$(out_base)/%: meta-automake-body = \
+$(call message,meta $(dist_prefix)$2/$(notdir $1),$(bld_root)/meta/automake \
+-o $(dist_prefix)$2/$(notdir $1) $1)
diff --git a/build/meta/automake.m4 b/build/meta/automake.m4
new file mode 100644
index 0000000..75f20c8
--- /dev/null
+++ b/build/meta/automake.m4
@@ -0,0 +1,19 @@
+m4_divert(-1)
+# file : build/meta/automake.m4
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+m4_include(__meta_base__`/common.m4')
+
+m4_define(`__path_impl__', `__env_impl__(`$1')')
+m4_define(`__path__', `m4_equote()__path_impl__(`$1')`'m4_dquote()')
+
+m4_define(`__file_impl__', `__env_impl__(`$1')')
+m4_define(`__file__', `m4_equote()__file_impl__(`$1')`'m4_dquote()')
+
+# Disable quoting.
+#
+m4_changequote('')
+
+m4_divert(0)dnl
diff --git a/build/meta/automake.make b/build/meta/automake.make
new file mode 100644
index 0000000..c38b370
--- /dev/null
+++ b/build/meta/automake.make
@@ -0,0 +1,6 @@
+# file : build/meta/automake.make
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(call include-once,$(bld_root)/meta/automake-functions.make,$(out_base))
diff --git a/build/meta/common.m4 b/build/meta/common.m4
new file mode 100644
index 0000000..54be556
--- /dev/null
+++ b/build/meta/common.m4
@@ -0,0 +1,76 @@
+# file : build/meta/common.m4
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+# Quote character literals.
+#
+m4_changequote([, ])
+m4_define([m4_oquote],`)
+m4_define([m4_cquote],')
+m4_changequote(`, ')
+
+# m4_strip(STRING)
+# ----------------
+# Expands into STRING with tabs and spaces singled out into a single
+# space, and removing leading and trailing spaces.
+#
+m4_define(`m4_strip',
+`m4_patsubst(m4_patsubst(` $1 ', `[ ]+', ` '), `^ \(.*\) $', ```\1''')')
+
+
+# m4_normalize(STRING)
+# --------------------
+# Apply m4_strip to STRING.
+#
+m4_define(`m4_normalize', `m4_strip(`$1')')
+
+# m4_split(STRING, [REGEXP])
+# --------------------------
+# Split STRING into an m4 list of quoted elements. The elements are
+# quoted with ' and '. Beginning spaces and end spaces *are kept*.
+# Use m4_strip to remove them.
+#
+# REGEXP specifies where to split. Default is [\t ]+.
+#
+# If STRING is empty, the result is an empty list.
+#
+
+m4_define(`m4_split',
+`m4_ifelse(`$1', `', `',
+ `$2', ` ', `m4_ifelse(m4_index(`$1', ` '), `-1', ```$1''',
+ `_$0(`$1', `$2', `, ')')',
+ `$2', `', `_$0(`$1', `[ ]+', `, ')',
+ `_$0(`$1', `$2', `, ')')')
+
+m4_define(`_m4_split', `m4_patsubst(`$1', `$2', `$3')')
+
+
+# Simple foreach implementation. The list elements are expected to
+# be fully expanded.
+#
+m4_define(`m4_foreach', `m4_ifelse(`$2', `', `',
+ `m4_pushdef(`$1')_$0(`$1', `$3', `', $2)m4_popdef(`$1')')')
+m4_define(`_m4_foreach', `m4_ifelse(`$#', `3', `',
+ `m4_define(`$1', `$4')$2`'$0(`$1', `$2',
+ m4_shift(m4_shift(m4_shift($@))))')')
+
+# m4_foreach_w(VARIABLE, LIST, EXPRESSION)
+# ----------------------------------------
+# Like m4_foreach, but the list is whitespace separated.
+#
+m4_define(`m4_foreach_w',
+`m4_foreach(`$1', m4_split(m4_normalize(`$2'), ` '), `$3')')
+
+# Enable/disable quoting.
+#
+m4_define(`m4_equote', `m4_changequote(`,')')
+m4_define(`m4_dquote', `m4_changequote(`')')
+
+#
+#
+m4_define(`__env_impl__', `m4_esyscmd(`echo -n $'`$1')')
+m4_define(`__env__', `m4_equote()__env_impl__(`$1')`'m4_dquote()')
+
+m4_define(`__value_impl__', `__env_impl__(`$1')')
+m4_define(`__value__', `m4_equote()__value_impl__(`$1')`'m4_dquote()')
diff --git a/build/meta/vc10proj b/build/meta/vc10proj
new file mode 100755
index 0000000..a8cae97
--- /dev/null
+++ b/build/meta/vc10proj
@@ -0,0 +1,78 @@
+#! /usr/bin/env bash
+
+# file : build/meta/vc10proj
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+# Process VC++ 10 project file templates.
+#
+# Options:
+#
+# -o <output-file>
+#
+# Arguments:
+#
+# <template-file>
+#
+trap 'exit 1' ERR
+
+function error ()
+{
+ echo "$*" 1>&2
+}
+
+output=
+
+while [ $# -gt 0 ]; do
+ case $1 in
+ -o)
+ output=$2
+ shift 2
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+input=$1
+
+if [ "$input" = "" ]; then
+ error "no input file"
+ exit 1
+fi
+
+if [ "$output" = "" ]; then
+ error "no output file"
+ exit 1
+fi
+
+m4=m4
+u2d=unix2dos
+
+# Assume this script is never found via PATH.
+#
+meta=`dirname $0`
+
+build="$meta/.."
+install=$build/install/install
+
+
+# Determine available configurations.
+#
+conf=`sed -n -e \
+'s/^[ ]*<ProjectConfiguration Include="\([^"]*\)">$/"\1",/p;d' $input`
+conf=`echo $conf | sed -e 's/,$//'`
+
+export configurations=$conf
+
+# Make sure the output directory exist.
+#
+$install -d -m 755 `dirname $output`
+
+$m4 -P -D__meta_base__=$meta $meta/vc10proj.m4 $input >$output
+$u2d $output
+
+$m4 -P -D__meta_base__=$meta $meta/vc10proj.m4 $input.filters >$output.filters
+$u2d $output.filters
diff --git a/build/meta/vc10proj-functions.make b/build/meta/vc10proj-functions.make
new file mode 100644
index 0000000..ff9265b
--- /dev/null
+++ b/build/meta/vc10proj-functions.make
@@ -0,0 +1,21 @@
+# file : build/meta/vc10proj-functions.make
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+# Process VC++ project file template and write output to $(dist_prefix)/<path>.
+# Where path is computed as difference between src_base and src_root.
+#
+# Arguments:
+#
+# $1 - template path
+#
+$(out_base)/%: meta-vc10proj = \
+$(call meta-vc10proj-body,$1,$(subst $(src_root),,$(src_base)))
+
+# $1 - template
+# $2 - difference between src_base and src_root with leading '\'
+#
+$(out_base)/%: meta-vc10proj-body = \
+$(call message,meta $(dist_prefix)$2/$(notdir $1),$(bld_root)/meta/vc10proj \
+-o $(dist_prefix)$2/$(notdir $1) $1)
diff --git a/build/meta/vc10proj.m4 b/build/meta/vc10proj.m4
new file mode 100644
index 0000000..9b8e2fd
--- /dev/null
+++ b/build/meta/vc10proj.m4
@@ -0,0 +1,109 @@
+m4_divert(-1)
+# file : build/meta/vc9proj.m4
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+m4_include(__meta_base__`/common.m4')
+
+m4_define(`__path_impl__', `m4_translit(__env_impl__(`$1'),`/',`\')')
+m4_define(`__path__', `m4_equote()__path_impl__(`$1')`'m4_dquote()')
+
+m4_define(`__file_impl__', `__env_impl__(`$1')')
+m4_define(`__file__', `m4_equote()__file_impl__(`$1')`'m4_dquote()')
+
+# header
+#
+m4_define(`__header_entry_impl__',
+` <ClInclude Include="`$1'" />')
+
+m4_define(`__header_entry__',
+`m4_equote()__header_entry_impl__(`$1')`'m4_equote()')
+
+
+m4_define(`__header_entries_impl__',
+`m4_foreach_w(`__f', __path_impl__(`$1'), `
+__header_entry_impl__(__f)')')
+
+m4_define(`__header_entries__',
+`m4_equote()__header_entries_impl__(`$1')`'m4_equote()')
+
+# header_filter
+#
+m4_define(`__header_filter_entry_impl__',
+` <ClInclude Include="`$1'">
+ <Filter>Header Files</Filter>
+ </ClInclude>')
+
+m4_define(`__header_filter_entry__',
+`m4_equote()__header_filter_entry_impl__(`$1')`'m4_equote()')
+
+
+m4_define(`__header_filter_entries_impl__',
+`m4_foreach_w(`__f', __path_impl__(`$1'), `
+__header_filter_entry_impl__(__f)')')
+
+m4_define(`__header_filter_entries__',
+`m4_equote()__header_filter_entries_impl__(`$1')`'m4_equote()')
+
+# source
+#
+
+# $1 - configuration
+# $2 - directory
+#
+m4_define(`__source_config_entry_impl__',
+` <ObjectFileName m4_dnl
+Condition="m4_cquote$(Configuration)|$(Platform)m4_cquote==m4_dnl
+m4_cquote`'m4_patsubst(`$1', `"', `')`'m4_cquote">m4_dnl
+$(IntDir)\`$2'\</ObjectFileName>')
+
+m4_define(`__source_entry_body__',
+`m4_ifelse(`$1', `$2',
+` <ClCompile Include="`$1'" />',
+` <ClCompile Include="`$1'">m4_dnl
+m4_foreach(`__c',
+`__value_impl__(`configurations')',
+`
+__source_config_entry_impl__(__c, `$2')')
+ </ClCompile>')')
+
+m4_define(`__source_entry_impl__',
+`__source_entry_body__(`$1',
+m4_patsubst(`$1', `^\(.*\)\\\(.*\)$', `\1'))')
+
+m4_define(`__source_entry__',
+`m4_equote()__source_entry_impl__(`$1')`'m4_equote()')
+
+m4_define(`__source_entries_impl__',
+`m4_foreach_w(`__f', __path_impl__(`$1'), `
+__source_entry_impl__(__f)')')
+
+m4_define(`__source_entries__',
+`m4_equote()__source_entries_impl__(`$1')`'m4_equote()')
+
+# source_filter
+#
+m4_define(`__source_filter_entry_impl__',
+` <ClCompile Include="`$1'">
+ <Filter>Source Files</Filter>
+ </ClCompile>')
+
+m4_define(`__source_filter_entry__',
+`m4_equote()__source_filter_entry_impl__(`$1')`'m4_equote()')
+
+
+m4_define(`__source_filter_entries_impl__',
+`m4_foreach_w(`__f', __path_impl__(`$1'), `
+__source_filter_entry_impl__(__f)')')
+
+m4_define(`__source_filter_entries__',
+`m4_equote()__source_filter_entries_impl__(`$1')`'m4_equote()')
+
+# Disable quoting.
+#
+m4_changequote(`')
+
+#
+
+m4_divert(0)m4_dnl
diff --git a/build/meta/vc10proj.make b/build/meta/vc10proj.make
new file mode 100644
index 0000000..7108931
--- /dev/null
+++ b/build/meta/vc10proj.make
@@ -0,0 +1,6 @@
+# file : build/meta/vc10proj.make
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(call include-once,$(bld_root)/meta/vc10proj-functions.make,$(out_base))
diff --git a/build/meta/vc9proj b/build/meta/vc9proj
new file mode 100755
index 0000000..7a19b11
--- /dev/null
+++ b/build/meta/vc9proj
@@ -0,0 +1,75 @@
+#! /usr/bin/env bash
+
+# file : build/meta/vc9proj
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+# Process VC++ 9 project file templates.
+#
+# Options:
+#
+# -o <output-file>
+#
+# Arguments:
+#
+# <template-file>
+#
+trap 'exit 1' ERR
+
+function error ()
+{
+ echo "$*" 1>&2
+}
+
+output=
+
+while [ $# -gt 0 ]; do
+ case $1 in
+ -o)
+ output=$2
+ shift 2
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+input=$1
+
+if [ "$input" = "" ]; then
+ error "no input file"
+ exit 1
+fi
+
+if [ "$output" = "" ]; then
+ error "no output file"
+ exit 1
+fi
+
+m4=m4
+u2d=unix2dos
+
+# Assume this script is never found via PATH.
+#
+meta=`dirname $0`
+
+build="$meta/.."
+install=$build/install/install
+
+
+# Determine available configurations.
+#
+conf=`sed -n -e \
+'/^[ ]*<Configuration$/{n;s/[ ]*Name="\([^"]*\)"$/"\1",/p};d' $input`
+conf=`echo $conf | sed -e 's/,$//'`
+
+export configurations=$conf
+
+# Make sure the output directory exist.
+#
+$install -d -m 755 `dirname $output`
+
+$m4 -P -D__meta_base__=$meta $meta/vc9proj.m4 $input >$output
+$u2d $output
diff --git a/build/meta/vc9proj-functions.make b/build/meta/vc9proj-functions.make
new file mode 100644
index 0000000..8329230
--- /dev/null
+++ b/build/meta/vc9proj-functions.make
@@ -0,0 +1,21 @@
+# file : build/meta/vc9proj-functions.make
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+# Process VC++ project file template and write output to $(dist_prefix)/<path>.
+# Where path is computed as difference between src_base and src_root.
+#
+# Arguments:
+#
+# $1 - template path
+#
+$(out_base)/%: meta-vc9proj = \
+$(call meta-vc9proj-body,$1,$(subst $(src_root),,$(src_base)))
+
+# $1 - template
+# $2 - difference between src_base and src_root with leading '\'
+#
+$(out_base)/%: meta-vc9proj-body = \
+$(call message,meta $(dist_prefix)$2/$(notdir $1),$(bld_root)/meta/vc9proj \
+-o $(dist_prefix)$2/$(notdir $1) $1)
diff --git a/build/meta/vc9proj.m4 b/build/meta/vc9proj.m4
new file mode 100644
index 0000000..a79355a
--- /dev/null
+++ b/build/meta/vc9proj.m4
@@ -0,0 +1,77 @@
+m4_divert(-1)
+# file : build/meta/vc9proj.m4
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+m4_include(__meta_base__`/common.m4')
+
+m4_define(`__path_impl__', `m4_translit(__env_impl__(`$1'),`/',`\')')
+m4_define(`__path__', `m4_equote()__path_impl__(`$1')`'m4_dquote()')
+
+m4_define(`__file_impl__', `__env_impl__(`$1')')
+m4_define(`__file__', `m4_equote()__file_impl__(`$1')`'m4_dquote()')
+
+# file
+#
+m4_define(`__file_entry_impl__',`
+ <File
+ RelativePath=".\`$1'"
+ >
+ </File>')
+
+m4_define(`__file_entry__',
+`m4_equote()__file_entry_impl__(`$1')`'m4_equote()')
+
+
+m4_define(`__file_entries_impl__',
+`m4_foreach_w(`__f', __path_impl__(`$1'), `__file_entry_impl__(__f)')')
+
+m4_define(`__file_entries__',
+`m4_equote()__file_entries_impl__(`$1')`'m4_equote()')
+
+# source
+#
+
+# $1 - configuration
+# $2 - directory
+#
+m4_define(`__source_config_entry_impl__',`
+ <FileConfiguration
+ Name=`$1'
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\`$2'\"
+ />
+ </FileConfiguration>')
+
+m4_define(`__source_config_impl__',
+`m4_ifelse(`$1', `$2', `',
+`m4_foreach(`__c',
+`__value_impl__(`configurations')',
+`__source_config_entry_impl__(__c, `$1')')')')
+
+m4_define(`__source_entry_impl__',`
+ <File
+ RelativePath=".\`$1'"
+ >m4_dnl
+__source_config_impl__(m4_patsubst(`$1', `^\(.*\)\\\(.*\)$', `\1'), `$1')
+ </File>')
+
+m4_define(`__source_entry__',
+`m4_equote()__source_entry_impl__(`$1')`'m4_equote()')
+
+m4_define(`__source_entries_impl__',
+`m4_foreach_w(`__f', __path_impl__(`$1'), `__source_entry_impl__(__f)')')
+
+m4_define(`__source_entries__',
+`m4_equote()__source_entries_impl__(`$1')`'m4_equote()')
+
+# Disable quoting.
+#
+m4_changequote(`')
+
+#
+
+m4_divert(0)m4_dnl
diff --git a/build/meta/vc9proj.make b/build/meta/vc9proj.make
new file mode 100644
index 0000000..55fc897
--- /dev/null
+++ b/build/meta/vc9proj.make
@@ -0,0 +1,6 @@
+# file : build/meta/vc9proj.make
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(call include-once,$(bld_root)/meta/vc9proj-functions.make,$(out_base))