trick/libexec/trick/make_makefile_swig
Alex Lin 1224c43e7f Set and use LD in our makefiles correctly.
Set LD in our makefiles to the ld executable found by configure.
Changed the final sim link to use TRICK_CPPC as the link command since
it was using the compiler anyways.  Changed the places where we use "ld" to
use LD.

refs #131
2016-06-27 12:48:35 -05:00

468 lines
17 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 strict ;
my @exclude_dirs ;
my @swig_exclude_dirs ;
my @files_to_process ;
my @ext_lib_files ;
sub get_exclude_dirs() {
@exclude_dirs = split /:/ , $ENV{"TRICK_EXCLUDE"};
# See if there are any elements in the exclude_dirs array
if (scalar @exclude_dirs) {
@exclude_dirs = sort(@exclude_dirs );
# Error check - delete any element that is null
# (note: sort forced all blank names to front of array
@exclude_dirs = map { s/(^\s+|\s+$)//g ; $_ } @exclude_dirs ;
while ( not length @exclude_dirs[0] ) {
# Delete an element from the left side of an array (element zero)
shift @exclude_dirs ;
}
@exclude_dirs = map { (-e $_) ? abs_path($_) : $_ } @exclude_dirs ;
}
@swig_exclude_dirs = split /:/ , $ENV{"TRICK_SWIG_EXCLUDE"};
# See if there are any elements in the swig_exclude_dirs array
if (scalar @swig_exclude_dirs) {
@swig_exclude_dirs = sort(@swig_exclude_dirs );
# Error check - delete any element that is null
# (note: sort forced all blank names to front of array
@swig_exclude_dirs = map { s/(^\s+|\s+$)//g ; $_ } @swig_exclude_dirs ;
while ( not length @swig_exclude_dirs[0] ) {
# Delete an element from the left side of an array (element zero)
shift @swig_exclude_dirs ;
}
@swig_exclude_dirs = map { (-e $_) ? abs_path($_) : $_ } @swig_exclude_dirs ;
}
# If there were no directories listed in TRICK_SWIG_EXCLUDE then copy the ones from ICG_EXCLUDE.
if ( scalar @swig_exclude_dirs == 0 ) {
@swig_exclude_dirs = split /:/ , $ENV{"TRICK_ICG_EXCLUDE"};
# See if there are any elements in the swig_exclude_dirs array
if (scalar @swig_exclude_dirs) {
@swig_exclude_dirs = sort(@swig_exclude_dirs );
# Error check - delete any element that is null
# (note: sort forced all blank names to front of array
@swig_exclude_dirs = map { s/(^\s+|\s+$)//g ; $_ } @swig_exclude_dirs ;
while ( not length @swig_exclude_dirs[0] ) {
# Delete an element from the left side of an array (element zero)
shift @swig_exclude_dirs ;
}
@swig_exclude_dirs = map { (-e $_) ? abs_path($_) : $_ } @swig_exclude_dirs ;
}
}
}
sub read_files_to_process() {
my @include_paths ;
my @icg_processed ;
my $cc ;
my @defines ;
my ($version, $thread, $year) ;
my $s_source_full_path = abs_path("S_source.hh") ;
my %compiler_file_list ;
open FILE, "build/ICG_processed" or die 'could not open build/ICG_processed' ;
@icg_processed = <FILE> ;
close FILE ;
chomp @icg_processed ;
($version, $thread) = get_trick_version() ;
($year) = $version =~ /^(\d+)/ ;
($cc = gte("TRICK_CC")) =~ s/\n// ;
@include_paths = $ENV{"TRICK_CFLAGS"} =~ /(-I\s*\S+)/g ; # get include paths from TRICK_CFLAGS
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") ;
@defines = $ENV{"TRICK_CFLAGS"} =~ /(-D\S+)/g ; # get defines from TRICK_CFLAGS
push @defines , "-DTRICK_VER=$year" ;
push @defines , "-DSWIG" ;
push @defines , "-std=c++11" ;
# Get the list header files from the compiler to compare to what get_headers processed.
open FILE_LIST, "$cc -MM @include_paths @defines S_source.hh |" ;
my $dir ;
$dir = dirname($s_source_full_path) ;
while ( <FILE_LIST> ) {
next if ( /^#/ or /^\s+\\/ ) ;
my $word ;
foreach $word ( split ) {
next if ( $word eq "\\" or $word =~ /o:/ ) ;
if ( $word !~ /^\// and $dir ne "\/" ) {
$word = "$dir/$word" ;
}
$word = abs_path(dirname($word)) . "/" . basename($word) ;
# filter out system headers that are missed by the compiler -MM flag
next if ( $word =~ /^\/usr\/include/) ;
#print "gcc found $word\n" ;
$compiler_file_list{$word} = 1 ;
}
}
foreach my $i ( @icg_processed ) {
$i = abs_path(dirname($i)) . "/" . basename($i) ;
if ( exists $compiler_file_list{$i} ) {
push @files_to_process , $i ;
}
}
open FILE, "build/ICG_ext_lib" or die 'could not open build/ICG_ext_lib' ;
my @unfiltered_ext_lib_files = <FILE> ;
close FILE ;
chomp @unfiltered_ext_lib_files ;
foreach my $e ( @unfiltered_ext_lib_files ) {
$e = abs_path(dirname($e)) . "/" . basename($e) ;
if ( exists $compiler_file_list{$e} ) {
push @ext_lib_files , $e ;
}
}
}
sub make_swig_makefile() {
my ($n , $f , $k , $m);
my %temp_hash ;
my ($ii) ;
my ($swig_sim_dir, $swig_src_dir) ;
my (%py_module_map) ;
my $s_source_full_path = abs_path("S_source.hh") ;
my $s_source_md5 = md5_hex($s_source_full_path) ;
$swig_sim_dir = "\$(CURDIR)/trick" ;
$swig_src_dir = "\$(CURDIR)/build" ;
foreach $n (@files_to_process) {
# check to see if the parent directory of each file is writable.
# If it isn't, then don't add it to the list of files to requiring ICG
$f = abs_path(dirname($n)) . "/" . basename($n) ;
my ($continue) = 1 ;
foreach my $ie ( @swig_exclude_dirs ) {
# if file location begins with $ie (an IGC exclude dir)
if ( $f =~ /^\Q$ie/ ) {
print "CP(swig) skipping $f (ICG exclude dir $ie)\n" ;
$continue = 0 ;
last ; # break out of loop
}
}
next if ( $continue == 0 ) ;
$temp_hash{$f} = 1;
}
@files_to_process = sort keys %temp_hash ;
open MAKEFILE , ">build/Makefile_swig" or return ;
open LINK_PY_OBJS , ">build/link_py_objs" or return ;
print LINK_PY_OBJS "build/init_swig_modules.o\n" ;
print LINK_PY_OBJS "build/py_top.o\n" ;
print MAKEFILE "\
# SWIG rule
SWIG_FLAGS ?=
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
ifdef TRICK_VERBOSE_BUILD
PRINT_SWIG =
PRINT_COMPILE_SWIG =
PRINT_SWIG_INC_LINK =
#PRINT_CONVERT_SWIG =
else
PRINT_SWIG = \@echo \"Swig  \$(subst \$(CURDIR)/build,build,\$<)\"
PRINT_COMPILE_SWIG = \@echo \"Compiling  \$(subst .o,.cpp,\$(subst \$(CURDIR)/build,build,\$@))\"
PRINT_SWIG_INC_LINK = \@echo \"Partial link swig objects\"
#PRINT_CONVERT_SWIG = \@echo \"Running convert_swig\"
endif
SWIG_MODULE_OBJECTS = \$(LIB_DIR)/swig_python.o
SWIG_PY_OBJECTS =" ;
foreach my $f ( @files_to_process ) {
my ($swig_dir, $swig_object_dir , $swig_module_dir , $swig_file_only) ;
my ($swig_f) = $f ;
$swig_object_dir = dirname($f) ;
($swig_file_only) = ($f =~ /([^\/]*)(?:\.h|\.H|\.hh|\.h\+\+|\.hxx|\.hpp)$/) ;
print MAKEFILE" \\\n \$(CURDIR)/build$swig_object_dir/py_${swig_file_only}.o" ;
}
print MAKEFILE "\\\n $swig_src_dir/init_swig_modules.o" ;
print MAKEFILE "\\\n $swig_src_dir/py_top.o\n\n" ;
print MAKEFILE "\$(SWIG_PY_OBJECTS) : | trick\n" ;
print MAKEFILE "trick :\n" ;
print MAKEFILE "\t\@mkdir \$\@\n" ;
my %swig_dirs ;
my %python_modules ;
$ii = 0 ;
foreach my $f ( @files_to_process ) {
my ($swig_dir, $swig_object_dir , $swig_module_dir , $swig_file_only) ;
my ($swig_f) = $f ;
# TODO: Add back python modules
# if ( $$sim_ref{python_module}{$f} ne "" ) {
# #print "python module for $f = $$sim_ref{python_module}{$f}\n" ;
# my ($temp_str) = $$sim_ref{python_module}{$f} ;
# $temp_str =~ s/\./\//g ;
# $swig_module_dir = "$temp_str/" ;
# $temp_str =~ $$sim_ref{python_module}{$f} ;
# $temp_str =~ s/\\/\./g ;
# push @{$python_modules{$temp_str}} , $f ;
# } else {
# $swig_module_dir = "" ;
push @{$python_modules{"root"}} , $f ;
# }
my $md5_sum = md5_hex($f) ;
# check if .sm file was accidentally ##included instead of #included
if ( rindex($swig_f,".sm") != -1 ) {
#trick_print($$sim_ref{fh}, "\nError: $swig_f should be in a #include not a ##include \n\n", "title_red", $$sim_ref{args}{v}) ;
exit -1 ;
}
$swig_f =~ s/([^\/]*)(?:\.h|\.H|\.hh|\.h\+\+|\.hxx|\.hpp)$/$1.i/ ;
$swig_file_only = $1 ;
my $link_py_obj = "build" . dirname($swig_f) . "/py_${swig_file_only}.o";
$swig_f = "\$(CURDIR)/build" . $swig_f ;
$swig_dir = dirname($swig_f) ;
$swig_object_dir = dirname($swig_f) ;
$swig_dirs{$swig_dir} = 1 ;
print MAKEFILE "$swig_object_dir/py_${swig_file_only}.o : $swig_f\n" ;
print MAKEFILE "\t\$(PRINT_SWIG)\n" ;
print MAKEFILE "\t\$(ECHO_CMD)\$(SWIG) \$(TRICK_INCLUDE) \$(TRICK_DEFINES) \$(TRICK_VERSIONS) \$(SWIG_FLAGS) -c++ -python -includeall -ignoremissing -w201,303,362,389,401,451 -outdir trick -o $swig_dir/py_${swig_file_only}.cpp \$<\n" ;
print MAKEFILE "\t\$(PRINT_COMPILE_SWIG)\n" ;
print MAKEFILE "\t\$(ECHO_CMD)\$(TRICK_CPPC) \$(TRICK_CXXFLAGS) \$(TRICK_SYSTEM_CXXFLAGS) \$(SWIG_CFLAGS) -c $swig_dir/py_${swig_file_only}.cpp -o \$@\n\n" ;
print LINK_PY_OBJS "$link_py_obj\n" ;
$ii++ ;
}
foreach $m ( keys %python_modules ) {
next if ( $m eq "root") ;
my ($temp_str) = $m ;
$temp_str =~ s/\./\//g ;
print MAKEFILE "$swig_sim_dir/$m:\n" ;
print MAKEFILE "\tmkdir -p \$@\n\n" ;
}
my $wd = abs_path(cwd()) ;
print MAKEFILE "
\$(SWIG_MODULE_OBJECTS) : TRICK_SYSTEM_CXXFLAGS += -Wno-unused-parameter -Wno-redundant-decls
OBJECTS += \$(SWIG_MODULE_OBJECTS)
LINK_OBJECTS += \$(SWIG_MODULE_OBJECTS)
\$(S_MAIN): \$(SWIG_MODULE_OBJECTS)
\$(SWIG_MODULE_OBJECTS) : \$(SWIG_PY_OBJECTS) | \$(LIB_DIR)
\t\$(PRINT_SWIG_INC_LINK)
\t\$(ECHO_CMD)\$(LD) \$(LD_PARTIAL) -o \$\@ \$(LD_FILELIST)build/link_py_objs
\n\n" ;
print MAKEFILE "$swig_src_dir/py_top.cpp : $swig_src_dir/top.i\n" ;
print MAKEFILE "\t\$(PRINT_SWIG)\n" ;
print MAKEFILE "\t\$(ECHO_CMD)\$(SWIG) \$(TRICK_INCLUDE) \$(TRICK_DEFINES) \$(TRICK_VERSIONS) -c++ -python -includeall -ignoremissing -w201,303,362,389,401,451 -outdir $swig_sim_dir -o \$@ \$<\n\n" ;
print MAKEFILE "$swig_src_dir/py_top.o : $swig_src_dir/py_top.cpp\n" ;
print MAKEFILE "\t\$(PRINT_COMPILE_SWIG)\n" ;
print MAKEFILE "\t\$(ECHO_CMD)\$(TRICK_CPPC) \$(TRICK_CXXFLAGS) \$(TRICK_SYSTEM_CXXFLAGS) \$(SWIG_CFLAGS) -c \$< -o \$@\n\n" ;
print MAKEFILE "$swig_src_dir/init_swig_modules.o : $swig_src_dir/init_swig_modules.cpp\n" ;
print MAKEFILE "\t\$(PRINT_COMPILE_SWIG)\n" ;
print MAKEFILE "\t\$(ECHO_CMD)\$(TRICK_CPPC) \$(TRICK_CXXFLAGS) \$(TRICK_SYSTEM_CXXFLAGS) \$(SWIG_CFLAGS) -c \$< -o \$@\n\n" ;
print MAKEFILE "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\n\n" ;
print MAKEFILE "S_main: \$(TRICK_FIXED_PYTHON)\n\n" ;
print MAKEFILE "\$(TRICK_FIXED_PYTHON) : $swig_sim_dir/\% : \${TRICK_HOME}/share/trick/swig/\%\n" ;
print MAKEFILE "\t\$(ECHO_CMD)/bin/cp -f \$< \$@\n\n" ;
foreach (keys %swig_dirs) {
print MAKEFILE "$_:\n" ;
print MAKEFILE "\tmkdir -p $_\n\n" ;
}
print MAKEFILE "\n" ;
close MAKEFILE ;
close LINK_PY_OBJS ;
open SWIGLIB , ">build/S_library_swig" or return ;
foreach my $f ( @files_to_process ) {
print SWIGLIB "$f\n" ;
}
close SWIGLIB ;
open S_INSTANCE , "build/CP_instances" or return ;
my @instances = <S_INSTANCE> ;
close S_INSTANCE ;
open TOPFILE , ">build/top.i" or return ;
print TOPFILE "\%module top\n\n" ;
print TOPFILE "\%{\n#include \"../S_source.hh\"\n\n" ;
print TOPFILE @instances ;
print TOPFILE "\n\%}\n\n" ;
print TOPFILE "\%import \"build$wd/S_source.i\"\n\n" ;
print TOPFILE @instances ;
close TOPFILE ;
open INITSWIGFILE , ">build/init_swig_modules.cpp" or return ;
print INITSWIGFILE "extern \"C\" {\n\n" ;
foreach $f ( @files_to_process ) {
my $md5_sum = md5_hex($f) ;
print INITSWIGFILE "void init_m${md5_sum}(void) ; /* $f */\n" ;
}
foreach $f ( @ext_lib_files ) {
my $md5_sum = md5_hex($f) ;
print INITSWIGFILE "void init_m${md5_sum}(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 ) {
next if ( $f =~ /S_source.hh/ ) ;
my $md5_sum = md5_hex($f) ;
print INITSWIGFILE " init_m${md5_sum}() ;\n" ;
}
foreach $f ( @ext_lib_files ) {
my $md5_sum = md5_hex($f) ;
print INITSWIGFILE " init_m${md5_sum}() ;\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" ;
close INITSWIGFILE ;
if ( ! -e "trick") {
mkdir "trick" ;
}
open INITFILE , ">trick/__init__.py" or return ;
print INITFILE "import sys\n" ;
print INITFILE "import os\n" ;
print INITFILE "sys.path.append(os.getcwd() + \"/trick\")\n" ;
foreach $m ( keys %python_modules ) {
next if ( $m eq "root") ;
my ($temp_str) = $m ;
$temp_str =~ s/\./\//g ;
print INITFILE "sys.path.append(os.getcwd() + \"/trick/$temp_str\")\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 $m ( keys %python_modules ) {
next if ( $m eq "root") ;
my ($temp_str) = $m ;
$temp_str =~ s/\//\./g ;
print INITFILE "import $temp_str\n" ;
}
print INITFILE "\n" ;
foreach $f ( @{$python_modules{"root"}} ) {
next if ( $f =~ /S_source.hh/ ) ;
my $md5_sum = md5_hex($f) ;
print INITFILE "# $f\n" ;
print INITFILE "import _m${md5_sum}\n" ;
print INITFILE "from m${md5_sum} import *\n" ;
print INITFILE "combine_cvars(all_cvars, cvar)\n" ;
print INITFILE "cvar = None\n\n" ;
}
foreach $f ( @ext_lib_files ) {
my $md5_sum = md5_hex($f) ;
print INITFILE "# $f\n" ;
print INITFILE "import _m${md5_sum}\n" ;
print INITFILE "from m${md5_sum} 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 ;
foreach $m ( keys %python_modules ) {
next if ( $m eq "root") ;
my ($temp_str) = $m ;
$temp_str =~ s/\./\//g ;
if ( ! -e "trick/$temp_str" ) {
mkpath("trick/$temp_str", {mode=>0775}) ;
}
open INITFILE , ">trick/$temp_str/__init__.py" or return ;
foreach $f ( @{$python_modules{$m}} ) {
next if ( $f =~ /S_source.hh/ ) ;
my $md5_sum = md5_hex($f) ;
print INITFILE "# $f\n" ;
print INITFILE "import _m${md5_sum}\n" ;
print INITFILE "from m${md5_sum} import *\n\n" ;
}
close INITFILE ;
while ( $temp_str =~ s/\/.*?$// ) {
open INITFILE , ">trick/$temp_str/__init__.py" or return ;
close INITFILE ;
}
}
open MAKEFILECONV , ">build/Makefile_convert_swig" or return ;
print MAKEFILECONV "\$(CURDIR)/build/convert_swig_last_run :" ;
foreach $f ( @files_to_process ) {
print MAKEFILECONV " \\\n $f" ;
}
close MAKEFILECONV ;
return ;
}
get_exclude_dirs() ;
read_files_to_process() ;
make_swig_makefile() ;