Commit 57f54689 authored by Roland Levillain's avatar Roland Levillain
Browse files

Import dynamic-use-of-static-c++.

	* dynamic-use-of-static-c++/: New directory.
	Fetched from
	https://svn.lrde.epita.fr/svn/oln/prototypes/dynamic-use-of-static-c++/trunk
	at revision 377.

git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@4640 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent c631719b
2009-06-08 Roland Levillain <roland@lrde.epita.fr>
Import dynamic-use-of-static-c++.
* dynamic-use-of-static-c++/: New directory.
Fetched from
https://svn.lrde.epita.fr/svn/oln/prototypes/dynamic-use-of-static-c++/trunk
at revision 377.
2009-10-16 Edwin Carlinet <carlinet@lrde.epita.fr>
Update configure.ac with AVS IO tests Makefile.
......
---
precious:
- repository
unmask:
- test/olena/proto-stl-style
- test/dyn.log
- libltdl
exclude:
- Makefile.in
- _build
- _config
- _install
# autotools stuffs
- configure
- autom4te.cache
- aclocal.m4
junk:
- \.gdb_history
- a.out
This diff is collapsed.
SUBDIRS = libltdl bin src config data test
ACLOCAL_AMFLAGS = -I config -I libltdl
EXTRA_DIST = bootstrap
HOW TO USE THIS PROJECT
From the repository:
# Initialize the build system
./bootstrap
# Make a build dir
mkdir _build && cd _build
# Configure the build for your system
# The config.site try to use more efficient tools (g++-4.0 and ccache)
# it also enable the configure caching.
# With --prefix you can set the destination (here _install)
CONFIG_SITE=`pwd`/../config.site ../configure --prefix=`pwd`/../_install
# For now need to add the bin directory to your path because dyn-config is
# by programs compiled with our system
export PATH=$PATH:`pwd`/bin
make check # The test with a latest prototype of olena will fail if you
# don't checkout it:
# cd test/olena && svn co https://svn.lrde.epita.fr/svn/oln/prototypes/proto-stl-style
bin_SCRIPTS = dyn-config
# FIXME put dyn- before these binaries
noinst_SCRIPTS = mk_swig_input swig_tree_to_yaml yaml_to_dyn_decls
BUILT_SOURCES = dyn-config
#!/usr/bin/env ruby
require 'optparse'
require 'pathname'
def expand ( var, binding )
var.gsub(/\$\{(.*)\}/) { eval($1, binding) }
end
name = 'libdyn'
version = '0.1'
prefix = Pathname.new('@prefix@')
includedir = expand('@includedir@', binding)
top_builddir = Pathname.new(__FILE__).dirname.parent
top_srcdir = expand('@top_srcdir@', binding)
exec_prefix = expand('@exec_prefix@', binding)
libdir = expand('@libdir@', binding)
libtool_flags = '-export-dynamic'
libdir_libdyn_la = Pathname.new("#{libdir}/libdyn.la")
if libdir_libdyn_la.exist? # FIXME Perhaps is assertion is bad.
cflags = "-I#{includedir}"
libtool = 'libtool' # Hope that libtool is installed
libtool_libs = "#{libdir_libdyn_la} #{libtool_flags}"
else
cflags = "-I#{top_builddir}/src -I#{top_srcdir}/src"
libtool_libs = "#{top_builddir}/src/libdyn.la #{libtool_flags}"
libtool = "#{top_builddir}/libtool"
end
o = OptionParser.new do |o|
o.banner { "Usage: #$0 [OPTION]" }
o.on('--prefix DIR',
"change #{name} prefix [default #{prefix}])") { |prefix| }
o.on('--exec-prefix DIR',
"change #{name} exec prefix [default #{exec_prefix}])") { |exec_prefix| }
# o.on('--libs', 'print library linking information') do
# end
o.on('--libtool-libs', 'print linking information for use with libtool') do
puts libtool_libs
end
o.on('--cflags', 'print pre-processor and compiler flags') do
puts cflags
end
o.on('--compile', 'compile line (add at least the input and the output)') do
puts "#{libtool} --mode=compile --tag=CXX ccache g++ -c #{cflags}"
end
o.on('--link', 'link line (add at least the input and the output)') do
puts "#{libtool} --mode=link --tag=CXX ccache g++ #{libtool_libs}"
end
o.on_tail('--help', 'display this help and exit') do
STDERR.puts o
exit
end
o.on_tail('--version', 'output version information') do
puts "#$0 #{version}"
end
end
puts o if ARGV.empty?
o.parse!(ARGV)
#!/usr/bin/env ruby
require 'pathname'
load Pathname.new(__FILE__).dirname.parent + 'configure'
includes = []
# dir = ARGV.shift
if ARGV.empty?
# STDERR.puts "usage #$0 <dir> <path/to/some/c++/headers.hh>*"
STDERR.puts "usage #$0 <dir>*"
exit
end
# patt = /\.t?h(h|xx)$/
patt = /\.t?hh$/
flags = '' # '-DVCSN_USE_INTERFACE_ONLY'
File.open('all.hh', 'w') do |all|
ARGV.each do |root|
Pathname.new(root).find do |path|
next unless path.to_s =~ patt
all.puts "#include \"#{path}\""
end
end
end
dirs = ARGV.map {|x| '-I' + x}
`g++ #{dirs.join ' '} -I. #{CFLAGS} -I#{DYNDIR} #{flags} -E all.hh | grep '^#.*vaucanson'`.to_a.reverse_each do |line|
line.chomp!
line.gsub!(/^.*include\/(vaucanson\/.*)".*$/, '\1')
next unless line =~ patt
next if line =~ /\/(static|letter|freemonoid_product(_base)?)\.hh/ # XXX hard skipping
includes << line unless includes.include? line
end
File.open('vcsn.i', 'w') do |vcsn_i|
includes.reverse_each do |include|
vcsn_i.puts "%include \"#{include}\""
end
vcsn_i.puts "%module vcsn"
end
#!/usr/bin/env ruby
str = STDIN.read
str.gsub!(/^(\s*) \+\+\+ (\w+) -+$/, '\1- \2:')
str.gsub!(/^(\s*)\+\+\+ (\w+) -+$/, '\1\2:')
str.gsub!(/^(\s*)\| (\S+)\s+- (.*)$/, '\1 \2: \3')
str.gsub!(/^$(\s*) -/, "\\1contents:\n\\1 -")
str.gsub!(/^\s*\|\s*$/, '')
puts str
#!/usr/bin/env ruby
require 'yaml'
require 'rubygems'
require_gem 'ruby_ex'
require 'ruby_ex'
require 'r_path'
require 'set'
require __FILE__.to_path.dirname.parent/'src/cxx_symbols'
tree = YAML.load STDIN.read
raise "Tree is Empty" if tree.nil?
class Hash
undef type
def name
# self['sym:name'] || super
super.gsub(/.*::/, '')
end
def method_missing ( meth )
self[meth.to_s]
end
end
class Dumper
def initialize
@namespace = []
@includes = []
@states = []
@all_methods = {}
@qualified_names = SortedSet[]
# @mlc_set_names = []
@io = STDOUT
@path_clean_re = /^.*\/include\/(.*)$/
end
def with ( io, &block )
oldio = @io
begin
@io = io
block[]
ensure
@io = oldio
end
end
def operator ( name )
mangle(name)
end
def puts ( *args )
@io.print ' ' * @namespace.size
@io.puts(*args)
end
def namespace ( name, &block )
puts "namespace #{name} {"
@namespace << name
@states << 'namespace'
block[]
@namespace.pop
@states.pop
puts "} // end of namespace #{name}"
end
def struct ( name, qualified_name, &block )
puts "// struct #{name} {"
@namespace << name
@states << 'struct'
block[]
unless @qualified_names.include? "ctor #{qualified_name}"
@qualified_names << "ctor #{qualified_name}"
puts "ctor #{name}(\"#{qualified_name}\");"
end
@namespace.pop
@states.pop
puts '// };'
end
def print_dyn ( key, tree )
return if tree.nil?
case tree
when Array
tree.each do |node|
print_dyn(nil, node)
end
return
when Hash
if tree.size == 1
print_dyn(*tree.to_a.first)
return
end
when String
return
end
key = tree.kind if key.nil? or (%w[template class].include? key)
# No struct specializations
return if tree.specialization == '1'
return if tree.partialspecialization == '1'
# No instance variables
return if key == 'cdecl' and not (tree.decl != '' and tree.access.nil?)
# No typdefs
return if tree.storage == 'typedef'
case key
when 'namespace'
namespace tree.name do
print_dyn nil, tree.contents
end
when 'struct', 'class'
name = (@namespace[1..-1] + [tree.name]).join('::')
unless @qualified_names.include? name
@qualified_names << name
=begin
case n = (parms = (tree.templateparms || '').split(/\s*,\s*/)).size
when 0 then @mlc_set_names << "mlc_set_name(#{name});"
else
b = -1
builtin_type = /bool|char/
parms.map! { |p| (p =~ builtin_type)? "#{p} B#{b += 1}" : p }
parm_names = parms.map { |p| p.split(/\s+/).last }
name_of = parms.map do |p|
var = p.split(/\s+/).last
case p
when /bool/ then "((#{var})? \"true\" : \"false\")"
when /char/ then "\"'\" + std::string(#{var}) + \"'\""
else "mlc_name<#{var}>::of()"
end
end.join(" + \", \" + ")
@mlc_set_names <<
"template <#{parms.join(', ')}> struct mlc_name " +
"< #{name}<#{parm_names.join(', ')}> > " +
"{ static std::string of() { return std::string(\"#{name}\") + " +
"\"< \" + #{name_of} + \" >\"; } };"
end
=end
end
struct tree.name, name do
print_dyn nil, tree.contents
end
when 'cdecl'
node_name = tree.name
if node_name =~ /operator/
node_name = operator(node_name)
end
name = (@namespace + [node_name]).join('::')
return if @qualified_names.include? name
@qualified_names << name
if @states.last == 'struct'
@all_methods[node_name] ||= Set.new
@all_methods[node_name] << @includes.last
else
puts "fun #{node_name}(\"#{name}\", \"\", \"#{@includes.last}\");"
end
when 'include'
@includes << tree.name
print_dyn nil, tree.contents
@includes.pop
# when 'constructor'
# dump "dyn::ctor(#{convert_params(tree.parms)})"
end
end
def print_all_methods
@all_methods.each { |k, v| @all_methods[k] = v.map { |x| x.gsub(@path_clean_re, '\1') } }
puts @all_methods.to_yaml
end
=begin
def print_mlc_set_names
@mlc_set_names.each do |mlc_set_name|
next if mlc_set_name =~ /TiSlot|PartialExp/ # XXX constant ignoring
puts mlc_set_name
end
end
=end
end
dumper = Dumper.new
root = tree.rpath_find(:first, ARGV[0] || 'top/contents/include/*name/vcsn\.i')
# puts root.to_yaml
puts '// ------------------------------------------------ '
puts '// dyn_vaucanson_dyn_mirror.hh'
File.open('dyn_vaucanson_dyn_mirror.hh', 'w') do |dyn_vaucanson_dyn_mirror_hh|
dumper.with(dyn_vaucanson_dyn_mirror_hh) do
dumper.namespace 'dyn' do
dumper.print_dyn nil, root['contents']
end
end
end
puts '// ------------------------------------------------ '
puts '// all_methods.yml'
File.open('dyn_vaucanson_methods.yml', 'w') do |all_methods_yml|
dumper.with(all_methods_yml) do
dumper.print_all_methods
end
end
=begin
puts '// ------------------------------------------------ '
puts '// dyn_vaucanson_mlc_name.hh'
File.open('dyn_vaucanson_mlc_name.hh', 'w') do |dyn_vaucanson_mlc_name_hh|
dumper.with(dyn_vaucanson_mlc_name_hh) do
dumper.print_mlc_set_names
end
end
=end
#!/bin/sh
# Failures do matter.
set -e
# Tell what's going on.
set -x
mkdir -p _config
touch _config/local-config.rb.in
# Make the libtool with ltdl
libtoolize --force --copy --automake --ltdl
# Finally, install the GNU Build System.
autoreconf -f -v -i
# FIXME: autoheader does not obey --force.
find . -name 'config.h*.in' -o -name 'local-config.*.in' | xargs touch
# -*- shell-script -*-
if test $PACKAGE_TARNAME == dyn; then
# Use the cache.
cache_file=config.cache
# Use a pretty recent GCC.
for i in -snapshot -4.0 ''
do
gcc$i --help >/dev/null 2>&1 &&
: ${CC=ccache gcc$i}
g++$i --help >/dev/null 2>&1 &&
: ${CXX=ccache g++$i}
done
# Don't optimize, but do debug.
: ${CXXFLAGS=-ggdb}
echo CC:$CC
echo CXX:$CXX
echo CXXFLAGS:$CXXFLAGS
else
echo "Loading config.site for the wrong package." >&2
fi
ruby.m4: rbconfig_gen.rb config/mk_local_config_rb_in.rb
#!/usr/bin/env ruby
# For this project only
DYN_MAX_ARGUMENTS = 10
ALL_METHODS = { 'fake_method' => ['*'] }
# end
require 'erb'
require 'pathname'
require 'optparse'
require 'ostruct'
opts = OpenStruct.new
opts.input_file = '-'
out = STDOUT
OptionParser.new do |o|
o.on('-c', '--copy', 'Copy the input before the result') { |opts.copy| }
o.on('-C', '--smart-copy', 'Smart copy see the manual') { |opts.smart_copy| }
o.on('-e', '--one-line INPUT', 'One line of input') { |opts.input_line| }
o.on('-i', '--input FILE', 'Input file (stdin by default)') { |opts.input_file| }
o.on('-o', '--output FILE', 'Output file (stdout by default)') do |output_file|
out_path = Pathname.new(output_file)
out_path.chmod(0644) if out_path.exist?
out = out_path.open('w')
out_path.chmod(0444) if out_path.exist?
end
o.on('--chomp', 'Remove the trailing new-line at the end') { |opts.chomp| }
o.on_tail('-h', '--help', 'This help message') { STDERR.puts o ; exit }
end.parse!(ARGV)
case opts.input_file
when '-'
input = opts.input_line || STDIN.read
else
input = File.read(opts.input_file)
end
print input if opts.copy
comment = '#erb# '
=begin
mode -C
example:
foo: do not touch me ...
=begin
erb code <%= 6 * 7 %>...
=end
bar: ...
become:
foo: do not touch me ...
#erb# =begin # Read the documentation of erbx to see how to change this part
#erb# erb code <%= 6 * 7 %>...
#erb# =end
#erb# =generated
erb code 42...
#erb# =end_generated
bar: ...
and this output can be an new input where the generated part
will be updated
=end
documentation = ' # Read the documentation of erbx to see how to change this part'
comment_re = /^#{comment}/
begin_re = /^(?:#{comment})?=begin[^\n]*$/
end_re = /^(?:#{comment})?=end$/
generated_re = /^#{comment}=generated$/
end_generated_re = /^#{comment}=end_generated$/
begin_t = "#{comment}=begin#{documentation}\n"
end_t = "#{comment}=end\n"
generated_t = "#{comment}=generated\n"
end_generated_t = "#{comment}=end_generated\n"
code = input[/#{begin_re}\n(.*)#{end_re}/m, 1]
code = input if code.nil? or code.empty?
code.gsub!(comment_re, '')
output = ERB.new(code, $SAFE, '<-%->', '$erbout_').result
if input =~ generated_re
input.gsub!(/\n(#{generated_re}).*(#{end_generated_re})/mx,
"\\1\n#{output}\\2")
else
input.gsub!(/(#{end_re}\n)/, "\\1#{generated_t}#{output}#{end_generated_t}")
end
if opts.smart_copy
code.gsub!(/^/, comment)
input.gsub!(/#{begin_re}.*#{end_re}/mx,
"#{begin_t}#{code}#{end_t}")
input.chomp!
out.print input
else
output.chomp!
out.print output
end
out.puts unless opts.input_line
out.close
require 'pathname'
# STDERR.puts "MK: #{ARGV.inspect}"
def usage
STDERR.puts "Usage: #$0 <dest-file>"
STDERR.puts "ac_subst_vars will be read from stdin"
exit
end
usage if ARGV.size != 1
out_path = Pathname.new ARGV.shift
args = STDIN.read.split(/\s+/)
out_path.chmod(0644) if out_path.exist?
out_path.open('w') do |out|
out.puts "# Generated by mk_local_config_rb_in.rb"
out.puts "# dest-file: #{out_path}"
out.puts "# ac_subst_vars: #{args.join(' ')}"
out.puts "AC_CONFIG = {"
args.each do |arg|
out.puts " :#{arg} => '@#{arg}@',"
end
out.puts "}"
end
out_path.chmod(0444)
require 'rbconfig'
def gen_m4 ( config )
config.each_key do |k|
name = "RUBY_#{k}"
puts %Q{
AC_SUBST([#{name}],
RUBY([
val = Config::CONFIG[%q[#{k}]]
val = val.to_s.gsub(%q['], %q['"'"'])
%q['] + val + %q[']
]))
AC_DEFINE([#{name}], $#{name},
[Contains Config::CONFIG['#{k}'] (generated by rbconfig_gen.rb)])
}
end
end
gen_m4(Config::CONFIG)
AC_DEFUN([RUBY],
[esyscmd([ruby <<\RUBY_EOF $2 $3 $4 $5 # and so on...
require "rbconfig"
block = proc do