multistage autogen en route

develop
jj 2012-04-05 16:46:07 +02:00
parent 3f39e285d0
commit 689cc50409
2 changed files with 42 additions and 9 deletions

@ -1,9 +1,26 @@
find_package(Ruby) find_package(Ruby)
if(RUBY_FOUND) if(RUBY_FOUND)
ADD_CUSTOM_COMMAND(
OUTPUT ruby-autogen.cpp
COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/codegen.pl ${dfhack_SOURCE_DIR}/library/include/df/codegen.out.xml ${CMAKE_CURRENT_BINARY_DIR}/ruby-autogen.cpp
DEPENDS ${dfhack_SOURCE_DIR}/library/include/df/codegen.out.xml codegen.pl
)
ADD_EXECUTABLE(ruby-autogen ruby-autogen.cpp)
ADD_CUSTOM_COMMAND(
OUTPUT ruby-autogen.offsets
COMMAND ruby-autogen ${CMAKE_CURRENT_BINARY_DIR}/ruby-autogen.offsets
DEPENDS ruby-autogen
)
ADD_CUSTOM_COMMAND(
OUTPUT ruby-autogen.rb
COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/codegen.pl ${dfhack_SOURCE_DIR}/library/include/df/codegen.out.xml ${CMAKE_CURRENT_SOURCE_DIR}/ruby-autogen.rb ${CMAKE_CURRENT_BINARY_DIR}/ruby-autogen.offsets
DEPENDS ruby-autogen.offsets
)
ADD_CUSTOM_TARGET(ruby-autogen-rb ALL DEPENDS ruby-autogen.rb)
include_directories("${dfhack_SOURCE_DIR}/depends/tthread" ${RUBY_INCLUDE_PATH}) include_directories("${dfhack_SOURCE_DIR}/depends/tthread" ${RUBY_INCLUDE_PATH})
DFHACK_PLUGIN(ruby ruby.cpp LINK_LIBRARIES dfhack-tinythread) DFHACK_PLUGIN(ruby ruby.cpp LINK_LIBRARIES dfhack-tinythread)
target_link_libraries(ruby ${RUBY_LIBRARY}) target_link_libraries(ruby ${RUBY_LIBRARY})
install(FILES ruby.rb DESTINATION ${DFHACK_LIBRARY_DESTINATION}) install(FILES ruby.rb ruby-autogen.rb DESTINATION ${DFHACK_LIBRARY_DESTINATION})
else(RUBY_FOUND) else(RUBY_FOUND)
MESSAGE(STATUS "Required library (ruby) not found - ruby plugin can't be built.") MESSAGE(STATUS "Required library (ruby) not found - ruby plugin can't be built.")
endif(RUBY_FOUND) endif(RUBY_FOUND)

@ -105,7 +105,7 @@ my $cpp_var_count = 0;
sub render_global_class { sub render_global_class {
my ($name, $type) = @_; my ($name, $type) = @_;
my $cppvar = "v_$cpp_var_count"; my $cppvar = "*v_$cpp_var_count";
$cpp_var_count += 1; $cpp_var_count += 1;
push @lines_cpp, "df::$name $cppvar;"; push @lines_cpp, "df::$name $cppvar;";
push @include_cpp, $name; push @include_cpp, $name;
@ -114,7 +114,7 @@ sub render_global_class {
my $parent = rb_ucase($type->getAttribute('inherits-from') || 'MemStruct'); my $parent = rb_ucase($type->getAttribute('inherits-from') || 'MemStruct');
push @lines_rb, "class $rbname < $parent"; push @lines_rb, "class $rbname < $parent";
indent_rb { indent_rb {
render_struct_fields($type, $cppvar); render_struct_fields($type, "($cppvar)");
}; };
push @lines_rb, "end"; push @lines_rb, "end";
} }
@ -283,7 +283,9 @@ sub render_item_bytes {
sub get_offset { sub get_offset {
my ($cppvar, $fname) = @_; my ($cppvar, $fname) = @_;
return query_cpp("offsetof(typeof($cppvar), $fname)"); # GCC fails with this
#return query_cpp("offsetof(typeof($cppvar), $fname)");
return query_cpp("((char*)&$cppvar.$fname - (char*)&$cppvar)");
} }
sub get_tglen { sub get_tglen {
@ -309,7 +311,7 @@ sub query_cpp {
my $ans = $offsets{$query}; my $ans = $offsets{$query};
return $ans if ($ans); return $ans if ($ans);
push @lines_cpp, "cout << \"$query = \" << $query << endl;"; push @lines_cpp, "fout << \"$query = \" << $query << std::endl;";
return "'$query'"; return "'$query'";
} }
@ -327,10 +329,12 @@ my $output = $ARGV[1] or die "need output file";
my $offsetfile = $ARGV[2]; my $offsetfile = $ARGV[2];
if ($offsetfile) { if ($offsetfile) {
while (<$offsetfile>) { open OF, "<$offsetfile";
my @val = split(' = '); while (<OF>) {
my @val = split(' = ', chomp);
$offsets{$val[0]} = $val[1]; $offsets{$val[0]} = $val[1];
} }
close OF;
} }
@ -356,9 +360,21 @@ for my $obj ($doc->findnodes('/ld:data-definition/ld:global-object')) {
open FH, ">$output"; open FH, ">$output";
if ($output =~ /\.cpp$/) { if ($output =~ /\.cpp$/) {
print FH "#include \"$_\"\n" for @include_cpp; print FH "#include \"Core.h\"\n";
print FH "void main(void) {\n"; print FH "#include \"Console.h\"\n";
print FH "#include \"Export.h\"\n";
print FH "#include \"PluginManager.h\"\n";
print FH "#include \"DataDefs.h\"\n";
print FH "#include \"df/$_.h\"\n" for @include_cpp;
print FH "#include <iostream>\n";
print FH "#include <fstream>\n";
print FH "int main(int argc, char **argv) {\n";
print FH " std::ofstream fout;\n";
print FH " if (argc < 2) return 1;\n";
print FH " fout.open(argv[1]);\n";
print FH " $_\n" for @lines_cpp; print FH " $_\n" for @lines_cpp;
print FH " fout.close();\n";
print FH " return 0;\n";
print FH "}\n"; print FH "}\n";
} else { } else {
print FH "$_\n" for @lines_rb; print FH "$_\n" for @lines_rb;