trick/libexec/trick/make_makefile_swig
2017-05-23 10:43:54 -05:00

363 lines
13 KiB
Perl
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/perl
use FindBin qw($RealBin);
use lib "$RealBin/pm" ;
use File::Basename ;
use Cwd ;
use Cwd 'abs_path';
use gte ;
use Digest::MD5 qw(md5_hex) ;
use trick_version ;
use html ;
use strict ;
my @exclude_paths ;
my @swig_exclude_paths ;
my @ext_lib_paths ;
my @files_to_process ;
my @ext_lib_files ;
my %md5s ;
my $verbose_build = exists($ENV{'TRICK_VERBOSE_BUILD'}) ;
sub get_paths {
my @paths = split /:/ , $ENV{$_[0]} ;
if (scalar @paths) {
@paths = sort(@paths ) ;
# trim whitespace
@paths = map { s/(^\s+|\s+$)//g ; $_ } @paths ;
# Remove empty elements. Sort forced all blank names to the front.
while ( not length @paths[0] ) {
shift @paths ;
}
@paths = map { (-e $_) ? abs_path($_) : $_ } @paths ;
}
return @paths ;
}
sub read_files_to_process() {
my @include_paths ;
my $cc ;
my @defines ;
my ($version, $thread, $year) ;
($version, $thread) = get_trick_version() ;
($year) = $version =~ /^(\d+)/ ;
($cc = gte("TRICK_CC")) =~ s/\n// ;
# add -I paths and #defines
foreach my $value ( "TRICK_CFLAGS", "TRICK_CXXFLAGS" ) {
push @include_paths, $ENV{$value} =~ /(-I\s*\S+)/g ;
push @defines, $ENV{$value} =~ /(-D\S+)/g ;
}
push @include_paths , ("-I".$ENV{"TRICK_HOME"}."/include") ;
push @include_paths , ("-I".$ENV{"TRICK_HOME"}."/include/trick/compat") ;
push @include_paths , ("-I".$ENV{"TRICK_HOME"}."/trick_source" , "-I../include") ;
push @defines , "-DTRICK_VER=$year" ;
push @defines , "-DSWIG" ;
push @defines , "-std=c++11" ;
# get the list of header files from the compiler
open FILE_LIST, "$cc -MM @include_paths @defines S_source.hh |" ;
my $dir ;
$dir = dirname(abs_path("S_source.hh")) ;
my %files ;
my %ext_libs ;
while ( <FILE_LIST> ) {
next if ( /^#/ or /^\s+\\/ ) ;
outer:
foreach my $word ( split ) {
next if ( $word eq "\\" or $word =~ /o:/ ) ;
# skip unsupported extensions
next if not $word =~ /\.(H|h|hh|hxx|h++|hpp)$/ ;
# get the absolute path
if ( $word !~ /^\// and $dir ne "\/" ) {
$word = "$dir/$word" ;
}
$word = abs_path(dirname($word)) . "/" . basename($word) ;
# skip duplicate files
next if (exists($md5s{$word})) ;
# skip system headers that are missed by the compiler -MM flag
next if ( $word =~ /^\/usr\/include/ ) ;
# skip Trick headers
my $trick_home = $ENV{'TRICK_HOME'} ;
next if ( $word =~ /^\Q$trick_home\/include/ ) ;
next if ( $word =~ /^\Q$trick_home\/trick_source/ ) ;
# skip paths in TRICK_EXCLUDE
foreach my $path ( @exclude_paths ) {
if ( $word =~ /^\Q$path\E(.*)/ ) {
print "SWIG Skip TRICK_EXCLUDE: $path$1\n" if $verbose_build ;
next outer ;
}
}
# skip paths in TRICK_SWIG_EXCLUDE
foreach my $path ( @swig_exclude_paths ) {
if ( $word =~ /^\Q$path\E(.*)/ ) {
print "SWIG Skip TRICK_SWIG_EXCLUDE: $path$1\n" if $verbose_build ;
next outer ;
}
}
# we'll be needing this later
$md5s{$word} = md5_hex($word) ;
# separate paths in TRICK_EXT_LIB_DIRS
foreach my $path ( @ext_lib_paths ) {
if ( $word =~ /^\Q$path\E(.*)/ ) {
print "SWIG Skip TRICK_EXT_LIB_DIRS: $path$1\n" if $verbose_build ;
$ext_libs{$word} = 1 ;
next outer ;
}
}
$files{$word} = 1 ;
}
}
@ext_lib_files = sort keys %ext_libs ;
@files_to_process = sort keys %files ;
}
sub write_makefile_swig_deps() {
open DEPENDENCIES_FILE , ">build/Makefile_swig_deps" or return ;
print DEPENDENCIES_FILE "build/Makefile_swig:" ;
foreach my $file ( @files_to_process, @ext_lib_files ) {
print DEPENDENCIES_FILE " \\\n " . $file ;
}
close DEPENDENCIES_FILE ;
}
sub has_swig_no($) {
my %trick_header = extract_trick_header( $_[0], do { local( @ARGV, $/ ) = $_[0] ; <> }, 0, 0 ) ;
my $result = $trick_header{swig} =~ /^NO$/i ;
print "SWIG Skip SWIG: (NO): $_[0]\n" if $verbose_build and $result ;
return $result ;
}
sub purge_swig_no_files() {
@files_to_process = grep { !has_swig_no($_) } @files_to_process ;
@ext_lib_files = grep { !has_swig_no($_) } @ext_lib_files ;
}
sub write_makefile_swig() {
my ($n , $f , $k , $m);
my %temp_hash ;
my ($ii) ;
my ($swig_sim_dir, $swig_src_dir) ;
my (%py_module_map) ;
my $s_source_md5 = md5_hex(abs_path("S_source.hh")) ;
$swig_sim_dir = "trick" ;
$swig_src_dir = "build" ;
open MAKEFILE , ">build/Makefile_swig" or return ;
open PY_LINK_LIST , ">build/py_link_list" or return ;
print PY_LINK_LIST "build/init_swig_modules.o\n" ;
print PY_LINK_LIST "build/top.o\n" ;
print MAKEFILE "SWIG_CFLAGS := -I../include \${PYTHON_INCLUDES} -Wno-shadow -Wno-missing-field-initializers
ifeq (\$(IS_CC_CLANG), 1)
SWIG_CFLAGS += -Wno-self-assign -Wno-sometimes-uninitialized -Wno-deprecated-register
endif
ifndef TRICK_VERBOSE_BUILD
PRINT_SWIG = \$(info \$(call COLOR,SWIGing) \$<)
PRINT_COMPILE_SWIG = \$(info \$(call COLOR,Compiling) \$<)
endif
# TRICK_FIXED_PYTHON ===========================================================
TRICK_FIXED_PYTHON = \\
$swig_sim_dir/swig_double.py \\
$swig_sim_dir/swig_int.py \\
$swig_sim_dir/swig_ref.py \\
$swig_sim_dir/shortcuts.py \\
$swig_sim_dir/unit_test.py \\
$swig_sim_dir/sim_services.py \\
$swig_sim_dir/exception.py
\$(TRICK_FIXED_PYTHON): $swig_sim_dir/\% : \${TRICK_HOME}/share/trick/swig/\%
\t\@echo /bin/cp -f \$< \$@ >> \$(MAKE_OUT)
\t\$(ECHO_CMD)/bin/cp -f \$< \$@ 2>&1 | \$(TEE) -a \$(MAKE_OUT) ; exit \$\${PIPESTATUS[0]}
all: \$(TRICK_FIXED_PYTHON)
# SWIG_I =======================================================================
SWIG_I =" ;
foreach my $file ( @files_to_process ) {
(my $swig_file = $file) =~ s/\.[^.]*$/_py.i/ ;
print MAKEFILE " \\\n build$swig_file" ;
$swig_file =~ s/i$/o/ ;
print PY_LINK_LIST "build$swig_file\n" ;
}
print MAKEFILE "
define create_convert_swig_rule
build/%_py.i: /%.\$1
\t\@echo \${TRICK_HOME}/\$(LIBEXEC)/trick/convert_swig \${TRICK_CONVERT_SWIG_FLAGS} \$\$< >> \$(MAKE_OUT)
\t\$(ECHO_CMD)\${TRICK_HOME}/\$(LIBEXEC)/trick/convert_swig \${TRICK_CONVERT_SWIG_FLAGS} \$\$< 2>&1 | \$(TEE) -a \$(MAKE_OUT) ; exit \$\${PIPESTATUS[0]}
endef
EXTENSIONS := H h hh hxx h++ hpp
\$(foreach EXTENSION,\$(EXTENSIONS),\$(eval \$(call create_convert_swig_rule,\$(EXTENSION))))
build/top.i: build/CP_instances
\t\@echo \${TRICK_HOME}/\${LIBEXEC}/trick/create_top_dot_i >> \$(MAKE_OUT)
\t\${ECHO_CMD}\${TRICK_HOME}/\${LIBEXEC}/trick/create_top_dot_i 2>&1 | \$(TEE) -a \$(MAKE_OUT) ; exit \$\${PIPESTATUS[0]}
# SWIG_SRC =====================================================================
SWIG_SRC = \$(subst .i,.cpp,\$(SWIG_I)) $swig_src_dir/top.cpp
\$(SWIG_SRC) : %.cpp: %.i | \$(SWIG_I)
\t\$(PRINT_SWIG)
\t\@echo \$(SWIG) \$(TRICK_INCLUDE) \$(TRICK_DEFINES) \$(TRICK_VERSIONS) \$(SWIG_FLAGS) -c++ -python -includeall -ignoremissing -w201,303,325,362,389,401,451 -outdir trick -o \$@ \$< >> \$(MAKE_OUT)
\t\$(ECHO_CMD)\$(SWIG) \$(TRICK_INCLUDE) \$(TRICK_DEFINES) \$(TRICK_VERSIONS) \$(SWIG_FLAGS) -c++ -python -includeall -ignoremissing -w201,303,325,362,389,401,451 -outdir trick -o \$@ \$< 2>&1 | \$(TEE) -a \$(MAKE_OUT) ; exit \$\${PIPESTATUS[0]}
# SWIG_OBJECTS =================================================================
SWIG_OBJECTS = \$(subst .cpp,.o,\$(SWIG_SRC)) $swig_src_dir/init_swig_modules.o
\$(SWIG_OBJECTS): %.o: %.cpp
\t\$(PRINT_COMPILE_SWIG)
\t\@echo \$(TRICK_CPPC) \$(TRICK_CXXFLAGS) \$(TRICK_SYSTEM_CXXFLAGS) \$(SWIG_CFLAGS) -Wno-unused-parameter -c -o \$@ \$< >> \$(MAKE_OUT)
\t\$(ECHO_CMD)\$(TRICK_CPPC) \$(TRICK_CXXFLAGS) \$(TRICK_SYSTEM_CXXFLAGS) \$(SWIG_CFLAGS) -Wno-unused-parameter -c -o \$@ \$< 2>&1 | \$(TEE) -a \$(MAKE_OUT) ; exit \$\${PIPESTATUS[0]}
\$(S_MAIN): \$(SWIG_OBJECTS)
LINK_LISTS += \$(LD_FILELIST)build/py_link_list
" ;
close MAKEFILE ;
close PY_LINK_LIST ;
open SWIGLIB , ">build/S_library_swig" or return ;
foreach my $f ( @files_to_process ) {
print SWIGLIB "$f\n" ;
}
close SWIGLIB ;
open INITSWIGFILE , ">build/init_swig_modules.cpp" or return ;
print INITSWIGFILE "#include <Python.h>\n" ;
print INITSWIGFILE "#if PY_VERSION_HEX >= 0x03000000\n" ;
print INITSWIGFILE "extern \"C\" {\n\n" ;
foreach $f ( @files_to_process, @ext_lib_files ) {
print INITSWIGFILE "PyObject * PyInit__m$md5s{$f}(void) ; /* $f */\n" ;
}
print INITSWIGFILE "PyObject * PyInit__sim_services(void) ;\n" ;
print INITSWIGFILE "PyObject * PyInit__top(void) ;\n" ;
print INITSWIGFILE "PyObject * PyInit__swig_double(void) ;\n" ;
print INITSWIGFILE "PyObject * PyInit__swig_int(void) ;\n" ;
print INITSWIGFILE "PyObject * PyInit__swig_ref(void) ;\n" ;
print INITSWIGFILE "\nvoid init_swig_modules(void) {\n\n" ;
foreach $f ( @files_to_process, @ext_lib_files ) {
next if ( $f =~ /S_source.hh/ ) ;
print INITSWIGFILE " PyImport_AppendInittab(\"_m$md5s{$f}\", PyInit__m$md5s{$f}) ;\n" ;
}
print INITSWIGFILE " PyImport_AppendInittab(\"_m${s_source_md5}\", PyInit__m${s_source_md5}) ;\n" ;
print INITSWIGFILE " PyImport_AppendInittab(\"_sim_services\", PyInit__sim_services) ;\n" ;
print INITSWIGFILE " PyImport_AppendInittab(\"_top\", PyInit__top) ;\n" ;
print INITSWIGFILE " PyImport_AppendInittab(\"_swig_double\", PyInit__swig_double) ;\n" ;
print INITSWIGFILE " PyImport_AppendInittab(\"_swig_int\", PyInit__swig_int) ;\n" ;
print INITSWIGFILE " PyImport_AppendInittab(\"_swig_ref\", PyInit__swig_ref) ;\n" ;
print INITSWIGFILE " return ;\n}\n\n}\n" ;
print INITSWIGFILE "#else\n" ;
print INITSWIGFILE "extern \"C\" {\n\n" ;
foreach $f ( @files_to_process, @ext_lib_files ) {
print INITSWIGFILE "void init_m$md5s{$f}(void) ; /* $f */\n" ;
}
print INITSWIGFILE "void init_sim_services(void) ;\n" ;
print INITSWIGFILE "void init_top(void) ;\n" ;
print INITSWIGFILE "void init_swig_double(void) ;\n" ;
print INITSWIGFILE "void init_swig_int(void) ;\n" ;
print INITSWIGFILE "void init_swig_ref(void) ;\n" ;
print INITSWIGFILE "\nvoid init_swig_modules(void) {\n\n" ;
foreach $f ( @files_to_process, @ext_lib_files) {
next if ( $f =~ /S_source.hh/ ) ;
print INITSWIGFILE " init_m$md5s{$f}() ;\n" ;
}
print INITSWIGFILE " init_m${s_source_md5}() ;\n" ;
print INITSWIGFILE " init_sim_services() ;\n" ;
print INITSWIGFILE " init_top() ;\n" ;
print INITSWIGFILE " init_swig_double() ;\n" ;
print INITSWIGFILE " init_swig_int() ;\n" ;
print INITSWIGFILE " init_swig_ref() ;\n" ;
print INITSWIGFILE " return ;\n}\n\n}\n" ;
print INITSWIGFILE "#endif\n" ;
close INITSWIGFILE ;
if ( ! -e "trick") {
mkdir "trick" ;
}
open INITFILE , ">trick/__init__.py" or return ;
print INITFILE "from pkgutil import extend_path\n" ;
print INITFILE "__path__ = extend_path(__path__, __name__)\n" ;
print INITFILE "import sys\n" ;
print INITFILE "import os\n" ;
print INITFILE "sys.path.append(os.getcwd() + \"/trick\")\n" ;
print INITFILE "\n" ;
print INITFILE "import _sim_services\n" ;
print INITFILE "from sim_services import *\n\n" ;
print INITFILE "# create \"all_cvars\" to hold all global/static vars\n" ;
print INITFILE "all_cvars = new_cvar_list()\n" ;
print INITFILE "combine_cvars(all_cvars, cvar)\n" ;
print INITFILE "cvar = None\n\n" ;
foreach $f ( @files_to_process, @ext_lib_files ) {
print INITFILE "# $f\n" ;
print INITFILE "import _m$md5s{$f}\n" ;
print INITFILE "from m$md5s{$f} import *\n" ;
print INITFILE "combine_cvars(all_cvars, cvar)\n" ;
print INITFILE "cvar = None\n\n" ;
}
print INITFILE "# S_source.hh\n" ;
print INITFILE "import _m${s_source_md5}\n" ;
print INITFILE "from m${s_source_md5} import *\n\n" ;
print INITFILE "import _top\n" ;
print INITFILE "import top\n\n" ;
print INITFILE "import _swig_double\n" ;
print INITFILE "import swig_double\n\n" ;
print INITFILE "import _swig_int\n" ;
print INITFILE "import swig_int\n\n" ;
print INITFILE "import _swig_ref\n" ;
print INITFILE "import swig_ref\n\n" ;
print INITFILE "from shortcuts import *\n\n" ;
print INITFILE "from exception import *\n\n" ;
print INITFILE "cvar = all_cvars\n\n" ;
close INITFILE ;
return ;
}
@exclude_paths = get_paths( "TRICK_EXCLUDE" ) ;
@swig_exclude_paths = get_paths( "TRICK_SWIG_EXCLUDE" ) ;
@ext_lib_paths = get_paths( "TRICK_EXT_LIB_DIRS" ) ;
read_files_to_process() ;
write_makefile_swig_deps() ;
# Remove SWIG: (NO) files, but not before they're written to the dependency file.
# If SWIG: (NO) is removed, Makefile_swig needs to be regenerated.
purge_swig_no_files() ;
write_makefile_swig() ;