diff --git a/bin/trick-CP b/bin/trick-CP index 024bd7187..35d3dab36 100755 --- a/bin/trick-CP +++ b/bin/trick-CP @@ -1,80 +1,120 @@ #!/usr/bin/perl +########## +# +# INPUTS: +# S_define in cwd +# +# OUTPUTS: +# Main sim makefile under TRICK_BUILD_DIR (if empty, cwd) +# +# PURPOSE: +# Start of the sim build process. Constructs the sims primary makefile and kicks it off. +# Also does command line parsing and attempts to run rebuild_trickify if available. +# +########## + # It is so hard getting the absolute path of the current script in bash # so I converted CP back to perl. :) -use File::Basename ; -use Cwd ; +use File::Basename; +use File::Spec; +use File::Path qw(make_path); +use Cwd; use Cwd 'abs_path'; -use Pod::Usage ; -use Pod::Text ; - -$trick_bin = dirname(abs_path($0)) ; -$trick_home = dirname($trick_bin) ; +use Pod::Usage; +use Pod::Text; +$my_cwd = getcwd(); +$trick_bin = dirname( abs_path($0) ); +$trick_home = dirname($trick_bin); ### Set TRICK_VERBOSE_BUILD if VERBOSE is defined (synonyms) ### -if(defined $ENV{'VERBOSE'}) { +if ( defined $ENV{'VERBOSE'} ) { $ENV{'TRICK_VERBOSE_BUILD'} = 1; } #### Handle arguments #### -$numArgs = $#ARGV + 1; +$numArgs = $#ARGV + 1; $makefileAddArgs = ' '; -$sdefine_dir = "."; -$sdefine = "S_define"; -$makefile = "makefile"; -foreach $argnum (0 .. $#ARGV) { +$sdefine_dir = "."; +$sdefine = "S_define"; +$trick_build_dir = "./"; +for $argnum ( 0 .. $#ARGV ) { $arg = $ARGV[$argnum]; - if ($arg =~ /(\w+)=(\w+)/ ) { + if ( $arg =~ /(\w+)=(\w+)/ ) { $makefileAddArgs = $makefileAddArgs . $1 . "=" . $2 . " "; - } elsif ($arg eq "-C" || $arg eq "--directory" ) { - $sdefine_dir = abs_path($ARGV[$argnum + 1]); + } + elsif ( $arg eq "-C" || $arg eq "--directory" ) { + $sdefine_dir = abs_path( $ARGV[ $argnum + 1 ] ); $makefileAddArgs = $makefileAddArgs . " -C $sdefine_dir "; - $sdefine = $sdefine_dir . "/${sdefine}"; - $makefile = $sdefine_dir . "/${makefile}"; - shift - } elsif ($arg =~ /-d/ ) { + $sdefine = $sdefine_dir . "/${sdefine}"; + $makefile = $sdefine_dir . "/${makefile}"; + shift; + } + elsif ( $arg =~ /-d/ ) { $makefileAddArgs = $makefileAddArgs . " debug "; - } elsif ($arg =~ /-t/ ) { + } + elsif ( $arg =~ /-t/ ) { $makefileAddArgs = $makefileAddArgs . " test "; - } elsif($arg=~ /-h/ ) { - pod2usage(-sections => "NAME|SYNOPSIS|DESCRIPTION|OPTIONS|FILES", -verbose => 99) ; - } else { - $ENV{TRICK_CPFLAGS} .= " $arg" ; } + elsif ( $arg =~ /-h/ ) { + pod2usage( -sections => "NAME|SYNOPSIS|DESCRIPTION|OPTIONS|FILES", -verbose => 99 ); + } + elsif ( $arg =~ /-b/ ) { + $trick_build_dir = File::Spec->catdir( $ARGV[ $argnum + 1 ], '' ) . "/"; + } + else { + $ENV{TRICK_CPFLAGS} .= " $arg"; + } +} +$makefile = "${trick_build_dir}makefile"; + +# Ensure build dir exists +unless ( -d $trick_build_dir ) { + make_path($trick_build_dir) or die "Could not create build dir: $trick_build_dir, $!\n"; } if ( -f $sdefine ) { - if ( not -w $sdefine_dir ) { - print $sdefine_dir , " is not writable\n" ; - print "trick-CP aborted\n" ; - exit 1 ; - } - unlink "build/Makefile_sim", $makefile ; - $makefile_text = do { local $/; } ; - $makefile_text =~ s/SUB_TRICK_HOME/$trick_home/ ; - $makefile_text =~ s/SUB_TRICK_BIN/$trick_bin/ ; - open MAKEFILE, ">$makefile" ; - print MAKEFILE $makefile_text ; - close MAKEFILE ; - - #Rebuild trickified libraries - if(not defined $ENV{'AM_I_TRICKIFYING'} and -e "trickify.mk") - { - my $cmd_ret = `make -f trickify.mk rebuild_trickify 2>&1` ; - if($cmd_ret ne "") - { - print "$cmd_ret" ; - } + if ( not -w $trick_build_dir ) { + print $sdefine_dir, " is not writable\n"; + print "trick-CP aborted\n"; + exit 1; } +} +else { + print "S_define does not exist\n"; + exit 1; +} - system("make -f makefile " . $makefileAddArgs) ; - exit $? >> 8; -} else { - print "S_define does not exist\n" ; - exit 1 ; +#If build dir starts with cwd dot remove it. +#We have to default to the cwd dot, otherwise -w fails. +$trick_build_dir =~ s/^\.\///; + +unlink "$trick_build_dir/Makefile_sim", $makefile; +$makefile_text = do { local $/; }; +$makefile_text =~ s/SUB_TRICK_HOME/$trick_home/; +$makefile_text =~ s/SUB_TRICK_BIN/$trick_bin/; +$ENV{'TRICK_SIM_DIR'} = "$my_cwd/"; +$ENV{'TRICK_BUILD_DIR'} = $trick_build_dir; + +open MAKEFILE, ">$makefile"; +print MAKEFILE $makefile_text; +close MAKEFILE; + +#Rebuild trickified libraries +if ( not defined $ENV{'AM_I_TRICKIFYING'} and -e "trickify.mk" ) { + my $cmd_ret = `make -f trickify.mk rebuild_trickify 2>&1`; + if ( $cmd_ret ne "" ) { + print "$cmd_ret"; + } } +system( "make -f ${trick_build_dir}makefile " . $makefileAddArgs ); + +# Dump the build dir readme +system("cp $trick_home/share/doc/trick/data/build_dir_readme ${trick_build_dir}build/README"); +exit $? >> 8; + # trick-CP help message =pod @@ -185,7 +225,14 @@ test: all debug: TRICK_CPFLAGS += --debug debug: all -build: +ifneq ($(TRICK_BUILD_DIR),) + TRICK_CXXFLAGS += -I $(TRICK_BUILD_DIR) + TRICK_CXXFLAGS += -I $(dir $(TRICK_BUILD_DIR)) + TRICK_CFLAGS += -I $(TRICK_BUILD_DIR) + TRICK_CFLAGS += -I $(dir $(TRICK_BUILD_DIR)) +endif + +$(TRICK_BUILD_DIR)build/: @mkdir -p $@ $(TRICK_STATIC_LIB): @@ -193,53 +240,59 @@ $(TRICK_STATIC_LIB): @exit -1 # CP creates S_source.hh required for ICG and SWIG processing -S_source.hh: S_define | build +$(TRICK_BUILD_DIR)S_source.hh: S_define | $(TRICK_BUILD_DIR)build/ $(PRINT_CP) $(call ECHO_AND_LOG,${TRICK_HOME}/$(LIBEXEC)/trick/configuration_processor $(TRICK_CPFLAGS)) -build/Makefile_S_define: S_source.hh +# Some developers add rules for S_define (as in the literal string S_define). +# In order to make things simple on their end, we allow them to reference the literal string S_define instead of $(TRICK_SIM_DIR)S_define +# By listing S_define as a S_source.hh dependency, we ensure the user's S_define rules are always invoked. +# The following rule checks that the actual S_define file exists in the sim dir. +S_define: $(TRICK_SIM_DIR)S_define + +$(TRICK_BUILD_DIR)build/Makefile_S_define: $(TRICK_BUILD_DIR)S_source.hh $(PRINT_S_DEF_DEPS) - $(call ECHO_AND_LOG,$(TRICK_CXX) $(TRICK_SFLAGS) $(TRICK_SYSTEM_SFLAGS) -MM -MT S_source.hh -MF build/Makefile_S_define -x c++ S_define) + $(call ECHO_AND_LOG,$(TRICK_CXX) $(TRICK_SFLAGS) $(TRICK_SYSTEM_SFLAGS) -MM -MT S_source.hh -MF $(TRICK_BUILD_DIR)build/Makefile_S_define -x c++ $(TRICK_SIM_DIR)S_define) # Automatic and manual ICG rules ICG: $(PRINT_ICG) - $(call ECHO_AND_LOG,${TRICK_HOME}/bin/trick-ICG -m ${TRICK_ICGFLAGS} ${TRICK_CXXFLAGS} ${TRICK_SYSTEM_CXXFLAGS} S_source.hh) + $(call ECHO_AND_LOG,${TRICK_HOME}/bin/trick-ICG -m ${TRICK_ICGFLAGS} ${TRICK_CXXFLAGS} ${TRICK_SYSTEM_CXXFLAGS} $(TRICK_BUILD_DIR)S_source.hh) force_ICG: $(PRINT_ICG) - $(call ECHO_AND_LOG,${TRICK_HOME}/bin/trick-ICG -force -m ${TRICK_ICGFLAGS} ${TRICK_CXXFLAGS} ${TRICK_SYSTEM_CXXFLAGS} S_source.hh) + $(call ECHO_AND_LOG,${TRICK_HOME}/bin/trick-ICG -force -m ${TRICK_ICGFLAGS} ${TRICK_CXXFLAGS} ${TRICK_SYSTEM_CXXFLAGS} $(TRICK_BUILD_DIR)S_source.hh) # Create makefile for IO code -build/Makefile_io_src: S_source.hh | build +$(TRICK_BUILD_DIR)build/Makefile_io_src: $(TRICK_BUILD_DIR)S_source.hh | $(TRICK_BUILD_DIR)build/ $(PRINT_ICG) $(call ECHO_AND_LOG,${TRICK_HOME}/bin/trick-ICG -m ${TRICK_ICGFLAGS} ${TRICK_CXXFLAGS} ${TRICK_SYSTEM_CXXFLAGS} $<) # Create makefile for source code -build/Makefile_src: build/Makefile_src_deps build/Makefile_io_src S_source.hh +$(TRICK_BUILD_DIR)build/Makefile_src: $(TRICK_BUILD_DIR)build/Makefile_src_deps $(TRICK_BUILD_DIR)build/Makefile_io_src $(TRICK_BUILD_DIR)S_source.hh $(PRINT_MAKEFILE_SRC) $(call ECHO_AND_LOG,${TRICK_HOME}/$(LIBEXEC)/trick/make_makefile_src $? 2>&1) -build/Makefile_src_deps: ; +$(TRICK_BUILD_DIR)build/Makefile_src_deps: ; # Create makefile for SWIG code -build/Makefile_swig: S_source.hh build/Makefile_swig_deps +$(TRICK_BUILD_DIR)build/Makefile_swig: $(TRICK_BUILD_DIR)S_source.hh $(TRICK_BUILD_DIR)build/Makefile_swig_deps $(PRINT_MAKEFILE_SWIG) $(call ECHO_AND_LOG,${TRICK_HOME}/$(LIBEXEC)/trick/make_makefile_swig) -build/Makefile_swig_deps: ; +$(TRICK_BUILD_DIR)build/Makefile_swig_deps: ; # Forcibly (re)create all SWIG input (.i) files. This rule is never run by the normal # build process. .PHONY: convert_swig -convert_swig: build/S_library_swig +convert_swig: $(TRICK_BUILD_DIR)build/S_library_swig $(call ECHO_AND_LOG,${TRICK_HOME}/$(LIBEXEC)/trick/convert_swig ${TRICK_CONVERT_SWIG_FLAGS}) # Force S_define_exp to be remade each time this rule runs .PHONY: S_define_exp S_define_exp: - $(TRICK_CC) -E -C -xc++ ${TRICK_SFLAGS} $(TRICK_SYSTEM_SFLAGS) S_define > $@ + $(TRICK_CC) -E -C -xc++ ${TRICK_SFLAGS} $(TRICK_SYSTEM_SFLAGS) $(TRICK_SIM_DIR)S_define > $@ # prints the value of a makefile variable, example invocation "make print-TRICK_CXXFLAGS" # This rule is used by trick-config @@ -258,21 +311,21 @@ Simulation make options:\n\ CLEAN_TARGETS = tidy clean spotless distclean apocalypse ifdef AM_I_TRICKIFYING -include build/Makefile_S_define -include build/Makefile_src +include $(TRICK_BUILD_DIR)build/Makefile_S_define +include $(TRICK_BUILD_DIR)build/Makefile_src else ifeq ($(findstring ${MAKECMDGOALS},$(CLEAN_TARGETS)),) -include build/Makefile_S_define -include build/Makefile_src -include build/Makefile_src_deps -include build/Makefile_io_src -include build/Makefile_swig -include build/Makefile_swig_deps --include build/Makefile_ICG +include $(TRICK_BUILD_DIR)build/Makefile_S_define +include $(TRICK_BUILD_DIR)build/Makefile_src +include $(TRICK_BUILD_DIR)build/Makefile_src_deps +include $(TRICK_BUILD_DIR)build/Makefile_io_src +include $(TRICK_BUILD_DIR)build/Makefile_swig +include $(TRICK_BUILD_DIR)build/Makefile_swig_deps +-include $(TRICK_BUILD_DIR)build/Makefile_ICG endif --include build/Makefile_overrides --include S_overrides.mk --include trickify.mk --include S_post.mk +-include $(TRICK_BUILD_DIR)build/Makefile_overrides +-include $(TRICK_SIM_DIR)S_overrides.mk +-include $(TRICK_BUILD_DIR)trickify.mk +-include $(TRICK_SIM_DIR)S_post.mk ifndef MAKE_RESTARTS REMOVE_MAKE_OUT := $(shell rm -f $(MAKE_OUT)) @@ -289,21 +342,21 @@ all: endif tidy: - -rm -f S_source.hh S_sie.resource S_sie.json - -rm -f S_main* T_main* - -rm -f build/Makefile_* + -rm -f $(TRICK_BUILD_DIR)S_source.hh $(TRICK_BUILD_DIR)S_sie.resource $(TRICK_BUILD_DIR)S_sie.json + -rm -f $(TRICK_BUILD_DIR)S_main* $(TRICK_BUILD_DIR)T_main* + -rm -f $(TRICK_BUILD_DIR)build/Makefile_* clean: tidy - -rm -f DP_Product/DP_rt_frame DP_Product/DP_rt_itimer - -rm -f DP_Product/DP_rt_jobs DP_Product/DP_rt_timeline DP_Product/DP_mem_stats - -rm -rf build .trick trick.zip - -rm -f makefile + -rm -f $(TRICK_BUILD_DIR)DP_Product/DP_rt_frame DP_Product/DP_rt_itimer + -rm -f $(TRICK_BUILD_DIR)DP_Product/DP_rt_jobs DP_Product/DP_rt_timeline DP_Product/DP_mem_stats + -rm -rf $(TRICK_BUILD_DIR)build/ $(TRICK_BUILD_DIR).trick $(TRICK_BUILD_DIR)trick.zip + -rm -f $(TRICK_BUILD_DIR)makefile spotless: clean distclean: clean -apocalypse: clean clean_trickify +apocalypse: spotless clean_trickify @echo "I love the smell of napalm in the morning <3" clean_trickify: ; diff --git a/bin/trick-ify b/bin/trick-ify index a18a6b1b9..97b6e8da0 100755 --- a/bin/trick-ify +++ b/bin/trick-ify @@ -1,7 +1,7 @@ #!/usr/bin/perl -use warnings ; -use strict ; +use warnings; +use strict; #clear certain environment variables. #these vars cause conflicts when trick-ify is invoked from the sim makefile @@ -12,639 +12,573 @@ $ENV{TRICK_EXT_LIB_DIRS} = ""; our %SHELL_ENV = %ENV; our $my_path; -BEGIN -{ - $my_path = $0 ; - $my_path =~ s/trick-ify// ; -} - -use File::Basename ; -use File::Find ; -use File::Path qw(make_path) ; -use Getopt::Long ; -use Cwd ; -use lib "$my_path../libexec/trick/pm" ; -use get_makefile_vars ; -use Term::ANSIColor ; - -sub printc($$) -{ - my ($color, $text) = @_ ; - print color($color) ; - print $text ; - print color('reset') ; -} -sub find_file_by_ext($$) -{ - my ($dirs_ref, $ext) = @_ ; - our @files_found = () ; - my $wanted = sub - { - if($_ =~ /\Q$ext\E$/) - { - push @files_found, $File::Find::name ; +BEGIN { + $my_path = $0; + $my_path =~ s/trick-ify//; +} + +use File::Basename; +use File::Find; +use File::Path qw(make_path); +use Getopt::Long; +use Cwd; +use lib "$my_path../libexec/trick/pm"; +use get_makefile_vars; +use trick_print; + +sub find_file_by_ext($$) { + my ( $dirs_ref, $ext ) = @_; + our @files_found = (); + my $wanted = sub { + if ( $_ =~ /\Q$ext\E$/ ) { + push @files_found, $File::Find::name; } }; - find($wanted, @$dirs_ref) ; + find( $wanted, @$dirs_ref ); } -our @files_found ; - -sub exclude_paths($$) -{ - my ($file_refs, $excl) = @_ ; - my @pruned_list ; - foreach my $file (@$file_refs) - { - if(($file =~ /^\Q$excl\E/) ne 1) - { - push @pruned_list, $file ; +our @files_found; + +sub exclude_paths($$) { + my ( $file_refs, $excl ) = @_; + my @pruned_list; + foreach my $file (@$file_refs) { + if ( ( $file =~ /^\Q$excl\E/ ) ne 1 ) { + push @pruned_list, $file; } } - @$file_refs = @pruned_list ; + @$file_refs = @pruned_list; } -sub filter_paths($$) -{ - my ($file_refs, $filters) = @_ ; - if(@$filters eq 0) - { - return 0 ; +sub filter_paths($$) { + my ( $file_refs, $filters ) = @_; + if ( @$filters eq 0 ) { + return 0; } - my @pruned_list ; - foreach my $file (@$file_refs) - { - my $include = 0 ; - foreach my $filter (@$filters) - { - if(($file =~ /^\Q$filter\E/) eq 1) - { - $include = 1 ; + my @pruned_list; + foreach my $file (@$file_refs) { + my $include = 0; + foreach my $filter (@$filters) { + if ( ( $file =~ /^\Q$filter\E/ ) eq 1 ) { + $include = 1; } } - if($include) - { - push @pruned_list, $file ; + if ($include) { + push @pruned_list, $file; } } - @$file_refs = @pruned_list ; + @$file_refs = @pruned_list; } -our @header_ext = (".h", ".hh", ".hpp", ".H", ".hxx", ".h++") ; -our @source_ext_cpp = (".cpp", ".cc", ".cxx", ".c++") ; -our @source_ext_c = (".c", ".C") ; -our @source_ext = (@source_ext_cpp, @source_ext_c) ; -our @trick_build_files = ("build/", "buildmodels/", "DP_Product/", "makefile", "python", "S_main_Linux_8.5_x86_64.exe", "S_sie.resource", "S_source.hh", "trick.zip", ".trick") ; -our $tmp_trick_build = "trickifying_tmp" ; +our @header_ext = ( ".h", ".hh", ".hpp", ".H", ".hxx", ".h++" ); +our @source_ext_cpp = ( ".cpp", ".cc", ".cxx", ".c++" ); +our @source_ext_c = ( ".c", ".C" ); +our @source_ext = ( @source_ext_cpp, @source_ext_c ); +our @trick_build_files = ( + "build/", "buildmodels/", "DP_Product/", "makefile", + "python", "S_main_Linux_8.5_x86_64.exe", "S_sie.resource", "S_source.hh", + "trick.zip", ".trick" +); +our $tmp_trick_build = "trickifying_tmp"; #Variables to store cmd line args -my $build_dir = getcwd ; # Where to build trickify artifacts -my $source_dirs = "" ; # User source code directories -my $source_make_call = "" ; # Make call to build object files -my $source_make_args = "" ; # Args to pass into default object make -my $trickify_make_args = "" ; # Arguments to pass into the trickify make -my $trickify_make_path = "$my_path../share/trick/makefiles/" ; # Path of the trickify make file -my $full_build = 1 ; # Whether to build only ICG/Swig artifacts or entire source -my $name = "trickified" ; # Name of the library -my $build_type = "o" ; # Type of library to be built (o, a , so) -my $debug = 0 ; # Debug info flag -my $trick_home = "$my_path.." ; # Trick directory to use for building -my $no_source_build = 0 ; # Arg to disable building source files -my $no_clean_obj = 0 ; # Don't rebuild trickify_obj_list -my $no_clean_src = 0 ; # Don't rebuild trickify_src_list -my $no_clean_s_source = 0 ; # Don't rebuild S_source.hh -my $s_overrides = "" ; # Optional S_override make file -my $include = "" ; # Directories to include when building source/ICG/SWIG files -my $exclude_arg = "" ; # Directories to exclude from trickification -my $s_define = "" ; # S_define to pull files from -my $s_define_filter = "" ; # Only use files from the S_define under these dirs +my $build_dir = getcwd; # Where to build trickify artifacts +my $source_dirs = ""; # User source code directories +my $source_make_call = ""; # Make call to build object files +my $source_make_args = ""; # Args to pass into default object make +my $trickify_make_args = ""; # Arguments to pass into the trickify make +my $trickify_make_path = "$my_path../share/trick/makefiles/"; # Path of the trickify make file +my $full_build = 1; # Whether to build only ICG/Swig artifacts or entire source +my $name = "trickified"; # Name of the library +my $build_type = "o"; # Type of library to be built (o, a , so) +my $debug = 0; # Debug info flag +my $trick_home = "$my_path.."; # Trick directory to use for building +my $no_source_build = 0; # Arg to disable building source files +my $no_clean_obj = 0; # Don't rebuild trickify_obj_list +my $no_clean_src = 0; # Don't rebuild trickify_src_list +my $no_clean_s_source = 0; # Don't rebuild S_source.hh +my $s_overrides = ""; # Optional S_override make file +my $include = ""; # Directories to include when building source/ICG/SWIG files +my $exclude_arg = ""; # Directories to exclude from trickification +my $s_define = ""; # S_define to pull files from +my $s_define_filter = ""; # Only use files from the S_define under these dirs our $stage = 1; -sub logStage() -{ - open my $fh, '>>', "$build_dir/trickify_stage_$stage" ; - $stage++ ; + +sub logStage() { + open my $fh, '>>', "$build_dir/trickify_stage_$stage"; + $stage++; } #Re-create the command line call -our @cmdline ; -push @cmdline, basename($0) ; +our @cmdline; +push @cmdline, basename($0); my $build_dir_found = 0; -foreach my $arg (@ARGV) -{ +foreach my $arg (@ARGV) { + #Since the makefile will be in the build dir, no need to pass the build directory. Can only cause problems. - if ( $build_dir_found ) - { - $build_dir_found = 0 ; - next ; + if ($build_dir_found) { + $build_dir_found = 0; + next; } - if ( $arg =~ /\Q-build\E/ ) - { - $build_dir_found = 1 ; - next ; + if ( $arg =~ /\Q-build\E/ ) { + $build_dir_found = 1; + next; } #restore quotes - if ( $arg !~ /^\-/ ) - { - push @cmdline, "\"$arg\"" ; + if ( $arg !~ /^\-/ ) { + push @cmdline, "\"$arg\""; } - else - { - push @cmdline, $arg ; + else { + push @cmdline, $arg; } } -our $cmdline = join ' ', @cmdline ; +our $cmdline = join ' ', @cmdline; #Process cmd line args -our %cmd_args ; -our @cmd_args ; -$cmd_args{"d=s"} = \$source_dirs; # User source code directories -$cmd_args{"no_clean_s_source"} = \$no_clean_s_source; # Don't rebuild S_source.hh -$cmd_args{"no_clean_src_list"} = \$no_clean_src; # Don't rebuild trickify_src_list -$cmd_args{"no_clean_obj_list"} = \$no_clean_obj; # Don't rebuild trickify_obj_list -$cmd_args{"no_source"} = \$no_source_build; # Arg to disable building source files -$cmd_args{"source_make=s"} = \$source_make_call; # Make call to build object files -$cmd_args{"source_make_args=s"} = \$source_make_args; # Default make call args to build object files -$cmd_args{"trickify_args=s"} = \$trickify_make_args; # Trickify make args -$cmd_args{"trickify_make=s"} = \$trickify_make_path; # Set trickify make path -$cmd_args{"n=s"} = \$name; # Set the library name -$cmd_args{"b=s"} = \$build_type; # Set library build type -$cmd_args{"v"} = \$debug; # Verbose, print debug info -$cmd_args{"trick_home=s"} = \$trick_home; # Set trick home directory -$cmd_args{"s_overrides=s"} = \$s_overrides; # Optional S_override make file -$cmd_args{"include=s"} = \$include; # Directories to include when building source/ICG/SWIG files -$cmd_args{"ex=s"} = \$exclude_arg; # Directories to exclude from trickification -$cmd_args{"build=s"} = \$build_dir; # Where to build trickify artifacts -$cmd_args{"s_define=s"} = \$s_define; # S_define to pull files from -$cmd_args{"s_define_filter=s"} = \$s_define_filter; # Only use files from the S_define under these dirs -foreach my $arg (sort keys %cmd_args) -{ - push @cmd_args, $arg ; - push @cmd_args, $cmd_args{$arg} ; -} -GetOptions(@cmd_args) ; +our %cmd_args; +our @cmd_args; +$cmd_args{"d=s"} = \$source_dirs; # User source code directories +$cmd_args{"no_clean_s_source"} = \$no_clean_s_source; # Don't rebuild S_source.hh +$cmd_args{"no_clean_src_list"} = \$no_clean_src; # Don't rebuild trickify_src_list +$cmd_args{"no_clean_obj_list"} = \$no_clean_obj; # Don't rebuild trickify_obj_list +$cmd_args{"no_source"} = \$no_source_build; # Arg to disable building source files +$cmd_args{"source_make=s"} = \$source_make_call; # Make call to build object files +$cmd_args{"source_make_args=s"} = \$source_make_args; # Default make call args to build object files +$cmd_args{"trickify_args=s"} = \$trickify_make_args; # Trickify make args +$cmd_args{"trickify_make=s"} = \$trickify_make_path; # Set trickify make path +$cmd_args{"n=s"} = \$name; # Set the library name +$cmd_args{"b=s"} = \$build_type; # Set library build type +$cmd_args{"v"} = \$debug; # Verbose, print debug info +$cmd_args{"trick_home=s"} = \$trick_home; # Set trick home directory +$cmd_args{"s_overrides=s"} = \$s_overrides; # Optional S_override make file +$cmd_args{"include=s"} = \$include; # Directories to include when building source/ICG/SWIG files +$cmd_args{"ex=s"} = \$exclude_arg; # Directories to exclude from trickification +$cmd_args{"build=s"} = \$build_dir; # Where to build trickify artifacts +$cmd_args{"s_define=s"} = \$s_define; # S_define to pull files from +$cmd_args{"s_define_filter=s"} = \$s_define_filter; # Only use files from the S_define under these dirs + +foreach my $arg ( sort keys %cmd_args ) { + push @cmd_args, $arg; + push @cmd_args, $cmd_args{$arg}; +} +GetOptions(@cmd_args); + +chdir Cwd::abs_path($build_dir) or die "Error changing to the build directory: $build_dir\n"; -chdir Cwd::abs_path($build_dir) or die "Error changing to the build directory: $build_dir\n" ; # Since we have already rebuilt the cmd line call, convert all paths into absolute paths to simplify everything -$source_dirs = join ' ', (map {Cwd::abs_path($_)} (split ' ', $source_dirs)) ; -$trick_home = join ' ', (map {Cwd::abs_path($_)} (split ' ', $trick_home)) ; -$s_overrides = join ' ', (map {Cwd::abs_path($_)} (split ' ', $s_overrides)) ; -$include = join ' ', (map {Cwd::abs_path($_)} (split ' ', $include)) ; -$exclude_arg = join ' ', (map {Cwd::abs_path($_)} (split ' ', $exclude_arg)) ; -$build_dir = join ' ', (map {Cwd::abs_path($_)} (split ' ', $build_dir)) ; -$s_define = join ' ', (map {Cwd::abs_path($_)} (split ' ', $s_define)) ; -$s_define_filter = join ' ', (map {Cwd::abs_path($_)} (split ' ', $s_define_filter)) ; -$trickify_make_path = join ' ', (map {Cwd::abs_path($_)} (split ' ', $trickify_make_path)) ; +$source_dirs = join ' ', ( map { Cwd::abs_path($_) } ( split ' ', $source_dirs ) ); +$trick_home = join ' ', ( map { Cwd::abs_path($_) } ( split ' ', $trick_home ) ); +$s_overrides = join ' ', ( map { Cwd::abs_path($_) } ( split ' ', $s_overrides ) ); +$include = join ' ', ( map { Cwd::abs_path($_) } ( split ' ', $include ) ); +$exclude_arg = join ' ', ( map { Cwd::abs_path($_) } ( split ' ', $exclude_arg ) ); +$build_dir = join ' ', ( map { Cwd::abs_path($_) } ( split ' ', $build_dir ) ); +$s_define = join ' ', ( map { Cwd::abs_path($_) } ( split ' ', $s_define ) ); +$s_define_filter = join ' ', ( map { Cwd::abs_path($_) } ( split ' ', $s_define_filter ) ); +$trickify_make_path = join ' ', ( map { Cwd::abs_path($_) } ( split ' ', $trickify_make_path ) ); # If we are trickifying, tells trick-CP to stop after trickify_deps is built -$ENV{'AM_I_TRICKIFYING'} = 1 ; -logStage(); #Stage 1 +$ENV{'AM_I_TRICKIFYING'} = 1; +logStage(); #Stage 1 # Ensure build dir exists -unless(-d $build_dir) -{ +unless ( -d $build_dir ) { make_path($build_dir) or die "Could not create build dir: $build_dir, $!\n"; } # If user provided an S_define, run a partial trick-CP and retrieve the lib dependencies -my $s_define_dir = "" ; +my $s_define_dir = ""; my @lib_deps_header; my @lib_deps_source; -if($s_define ne "") -{ - - $s_define_dir = dirname($s_define) ; - chdir Cwd::abs_path($s_define_dir) or die "Error changing to the s_define directory: $s_define_dir\n" ; - - # If the user has already built the sim, push it somewhere else - map - { - if(-e $_) - { - system("mv $_ $tmp_trick_build$_") == 0 or die "Could not move $_\n" ; - } +if ( $s_define ne "" ) { + + #Clean up tmp build if it already exists + if ( -d "$build_dir/tmp_build" ) { + chdir Cwd::abs_path("$build_dir/tmp_build") + or die "Error changing to the build directory: $build_dir/tmp_build\n"; + system('make clean'); + chdir Cwd::abs_path("$build_dir") or die "Error changing to the build directory: $build_dir\n"; + system('rm -r tmp_build'); } - @trick_build_files; - my $cmd_ret = `$my_path/trick-CP 2>&1` ; - if($cmd_ret ne "") - { - print "$cmd_ret" ; + $s_define_dir = dirname($s_define); + chdir Cwd::abs_path($s_define_dir) or die "Error changing to the s_define directory: $s_define_dir\n"; + + my $cmd_ret = `$my_path/trick-CP -b $build_dir/tmp_build 2>&1`; + if ( $cmd_ret ne "" ) { + print "$cmd_ret"; } - -e "build/trickify_deps" or die "Failed to create trickify_deps from S_define.\n" ; - - open (my $fh, "build/trickify_deps") or die "Could not open trickify_deps" ; - while (my $line = <$fh>) - { - chomp $line ; - if($line =~ /\QS_source.hh\E$/) - { - next ; - } - if(scalar grep {$line =~ /\Q$_\E$/} @source_ext) - { - push @lib_deps_source, $line ; + -e "$build_dir/tmp_build/build/trickify_deps" or die "Failed to create trickify_deps from S_define.\n"; + + open( my $fh, "$build_dir/tmp_build/build/trickify_deps" ) or die "Could not open trickify_deps"; + while ( my $line = <$fh> ) { + chomp $line; + if ( $line =~ /\QS_source.hh\E$/ ) { + next; } - else - { - push @lib_deps_header, $line ; + if ( scalar grep { $line =~ /\Q$_\E$/ } @source_ext ) { + push @lib_deps_source, $line; } - } - close ($fh) ; - - # Clear up the partial build dir we just made - system("make clean") == 0 or die "Could not clean up tmp build dir\n" ; - - map - { - if(-e "$tmp_trick_build$_") - { - system("mv $tmp_trick_build$_ $_") == 0 or die "Could not move $_\n" ; + else { + push @lib_deps_header, $line; } } - @trick_build_files; + close($fh); } -my @filters = split ' ', $s_define_filter ; -filter_paths(\@lib_deps_source, \@filters) ; -filter_paths(\@lib_deps_header, \@filters) ; +my @filters = split ' ', $s_define_filter; +filter_paths( \@lib_deps_source, \@filters ); +filter_paths( \@lib_deps_header, \@filters ); -chdir Cwd::abs_path($build_dir) or die "Error changing to build directory: $build_dir\n" ; +chdir Cwd::abs_path($build_dir) or die "Error changing to build directory: $build_dir\n"; # Split the s_overrides path into a dir and file name -my $s_overrides_dir = "" ; -if ($s_overrides ne "") -{ - $s_overrides_dir = dirname($s_overrides) ; +my $s_overrides_dir = ""; +if ( $s_overrides ne "" ) { + $s_overrides_dir = dirname($s_overrides); } -$full_build = !$no_source_build ; +$full_build = !$no_source_build; -if( !(($build_type eq "o") or ($build_type eq "a") or ($build_type eq "so") or ($build_type eq "dylib")) ) -{ - print "Invalid build type {$build_type}, valid build types are {o, a, so}\n" ; - exit 1 ; +if ( !( ( $build_type eq "o" ) or ( $build_type eq "a" ) or ( $build_type eq "so" ) or ( $build_type eq "dylib" ) ) ) { + print "Invalid build type {$build_type}, valid build types are {o, a, so}\n"; + exit 1; } -if($s_define eq "") -{ - if($source_dirs eq "" and $full_build) - { - print "Must provide source directories or S_define\n" ; - exit 1 ; +if ( $s_define eq "" ) { + if ( $source_dirs eq "" and $full_build ) { + print "Must provide source directories or S_define\n"; + exit 1; } } #Build list of includes for compilation. my $include_arg = ""; -my @incl_dirs = split ' ', $include ; -foreach my $dir (@incl_dirs) -{ - $include_arg .= "-I$dir " ; +my @incl_dirs = split ' ', $include; +foreach my $dir (@incl_dirs) { + $include_arg .= "-I$dir "; } #Set Environment Variables -if ($full_build) -{ - $ENV{'FULL_TRICKIFY_BUILD'} = "1" ; -} -my @src_dirs = split ' ', $source_dirs ; -my $source_dir_args = "" ; -foreach my $dir (@src_dirs) -{ - $source_dir_args .= "-I" . $dir . " " ; -} -$ENV{'TRICKIFY_CXX_FLAGS'} = "$source_dir_args -I$trick_home -I$trick_home/include/trick/compat -I${trick_home}/include -I$trick_home/trick_source -I$trick_home/trick_source/er7_utils -I$trick_home/trick_source/er7_utils $include_arg " . $ENV{"TRICK_CFLAGS"} . " " . $ENV{"TRICK_CXXFLAGS"} ; -$ENV{'TRICKIFY_OBJECT_NAME'} = "$build_dir/$name.$build_type" ; -$ENV{'TRICKIFY_BUILD'} = "$build_dir/" ; -$ENV{'TRICKIFY_PYTHON_DIR'} = "$build_dir/python" ; -$ENV{'TRICKIFY_S_OVERRIDES'} = "$s_overrides" ; -our @exclude_list = split ' ', $exclude_arg ; -if ( $build_type eq "o" ) -{ - $ENV{'TRICKIFY_BUILD_TYPE'} = "PLO" ; -} -elsif ( $build_type eq "a" ) -{ - $ENV{'TRICKIFY_BUILD_TYPE'} = "STATIC" ; -} -elsif ( $build_type eq "so" || $build_type eq "dylib" ) -{ - $ENV{'TRICKIFY_BUILD_TYPE'} = "SHARED" ; - if ($^O eq "linux") - { - $source_make_args .= " -fPIC" ; +if ($full_build) { + $ENV{'FULL_TRICKIFY_BUILD'} = "1"; +} +my @src_dirs = split ' ', $source_dirs; +my $source_dir_args = ""; +foreach my $dir (@src_dirs) { + $source_dir_args .= "-I" . $dir . " "; +} +$ENV{'TRICKIFY_CXX_FLAGS'} = + "$source_dir_args -I$trick_home -I$trick_home/include/trick/compat -I${trick_home}/include -I$trick_home/trick_source -I$trick_home/trick_source/er7_utils -I$trick_home/trick_source/er7_utils $include_arg " + . $ENV{"TRICK_CFLAGS"} . " " + . $ENV{"TRICK_CXXFLAGS"}; +$ENV{'TRICKIFY_OBJECT_NAME'} = "$build_dir/$name.$build_type"; +$ENV{'TRICKIFY_BUILD'} = "$build_dir/"; +$ENV{'TRICKIFY_PYTHON_DIR'} = "$build_dir/python"; +$ENV{'TRICKIFY_S_OVERRIDES'} = "$s_overrides"; +our @exclude_list = split ' ', $exclude_arg; +if ( $build_type eq "o" ) { + $ENV{'TRICKIFY_BUILD_TYPE'} = "PLO"; +} +elsif ( $build_type eq "a" ) { + $ENV{'TRICKIFY_BUILD_TYPE'} = "STATIC"; +} +elsif ( $build_type eq "so" || $build_type eq "dylib" ) { + $ENV{'TRICKIFY_BUILD_TYPE'} = "SHARED"; + if ( $^O eq "linux" ) { + $source_make_args .= " -fPIC"; } } #Build the S_overrides_trickify.mk -print "Building S_overrides_trickify.mk\n" ; -my $ext_lib_dir ; -$ext_lib_dir .= join '', (map {":$_"} (split ' ', $source_dirs)) ; -$ext_lib_dir .= join '', (map {":$_"} @filters) ; -my $ext_lib_dir_overrides = join '', (map {":$_"} @exclude_list) ; +print "Building S_overrides_trickify.mk\n"; +my $ext_lib_dir; +$ext_lib_dir .= join '', ( map { ":$_" } ( split ' ', $source_dirs ) ); +$ext_lib_dir .= join '', ( map { ":$_" } @filters ); +my $ext_lib_dir_overrides = join '', ( map { ":$_" } @exclude_list ); #if the user provides an s_define, we automatically exclude that dir from ext_lib_dirs -if ($s_define_dir ne "") -{ - push @exclude_list, "$s_define_dir/build/" ; - push @exclude_list, "$s_define_dir/S_source.hh" ; +if ( $s_define_dir ne "" ) { + push @exclude_list, "$s_define_dir/build/"; + push @exclude_list, "$s_define_dir/S_source.hh"; } my $my_cwd = getcwd; -#TODO: Might want to add an option to make this a relative path. -open (my $fh, ">", "S_overrides_trickify.mk") or die "Could not open S_overrides_trickify.mk\n" ; -print $fh "ifndef AM_I_TRICKIFYING\n" ; # Only want these parameters if we are doing normal sim builds, otherwise the ext libs will butcher the trickify_deps -print $fh "SOT_LOCAL_DIR_$name := \$(abspath \$(dir \$(lastword \$(MAKEFILE_LIST))))\n\n" ; -print $fh "include $build_dir/trickify_dep.mk\n\n" ; -print $fh "TRICKIFY_LDFLAGS := " . Cwd::abs_path($ENV{'TRICKIFY_OBJECT_NAME'}) . "\n" ; -print $fh "TRICK_EXT_LIB_DIRS += $ext_lib_dir\n" ; -print $fh "TRICK_EXT_LIB_DIRS_OVERRIDES += ",$ext_lib_dir_overrides ,"\n" ; -print $fh "TRICK_PYTHON_PATH += :" . $my_cwd . "/python\n" ; -print $fh "TRICK_SWIG_FLAGS += -I" . $my_cwd . "\n" ; -print $fh "\nclean_trickify_$name:\n" ; -print $fh "\t-make -C \$(SOT_LOCAL_DIR_$name) clean_trickify\n" ; -print $fh "\nclean_trickify: clean_trickify_$name\n" ; -print $fh "\nnuke_trickify_$name:\n" ; -print $fh "\t-make -C \$(SOT_LOCAL_DIR_$name) nuke_trickify\n" ; -print $fh "\nnuke_trickify: nuke_trickify_$name\n" ; -print $fh "\nrebuild_trickify: $build_dir/$name.$build_type\n" ; -print $fh "\nTRICKIFIED_LIBS += $build_dir/$name.$build_type\n" ; -print $fh "\nendif\n" ; -close ($fh) ; - -open ($fh, ">", "makefile") or die "Could not create makefile\n" ; -print $fh "\nrebuild_trickify: \n" ; -print $fh "\t+$cmdline\n" ; -print $fh "\nclean_trickify:\n" ; -print $fh "\t-rm -rf build .trick\n" ; -print $fh "\t-rm -f S_source.hh\n" ; -print $fh "\t-rm -f trickify_obj_list\n" ; -print $fh "\t-rm -f trickify_src_list\n" ; -print $fh "\t-rm -f trickify_stage_*\n" ; -print $fh "\t-rm -f trickify.log\n" ; -print $fh "\t-rm -f get_vars.mk\n" ; -print $fh "\t-rm -f var_dump.mk\n" ; -print $fh "\t-rm -f *_list\n" ; -print $fh "\t-rm -f python\n" ; -print $fh "\t-rm -f *.a\n" ; -print $fh "\t-rm -f *.o\n" ; -print $fh "\t-rm -f *.so\n" ; -print $fh "\nnuke_trickify: clean_trickify\n" ; -print $fh "\t-rm -f S_overrides_trickify.mk\n" ; -print $fh "\t-rm -f *.mk\n" ; -close ($fh) ; +#TODO: Might want to add an option to make this a relative path. +open( my $fh, ">", "S_overrides_trickify.mk" ) or die "Could not open S_overrides_trickify.mk\n"; +print $fh "ifndef AM_I_TRICKIFYING\n" + ; # Only want these parameters if we are doing normal sim builds, otherwise the ext libs will butcher the trickify_deps +print $fh "SOT_LOCAL_DIR_$name := \$(abspath \$(dir \$(lastword \$(MAKEFILE_LIST))))\n\n"; +print $fh "include $build_dir/trickify_dep.mk\n\n"; +print $fh "TRICKIFY_LDFLAGS += " . Cwd::abs_path( $ENV{'TRICKIFY_OBJECT_NAME'} ) . "\n"; +print $fh "TRICK_EXT_LIB_DIRS += $ext_lib_dir\n"; +print $fh "TRICK_EXT_LIB_DIRS_OVERRIDES += ", $ext_lib_dir_overrides, "\n"; +print $fh "TRICK_PYTHON_PATH += :" . $my_cwd . "/python\n"; +print $fh "TRICK_SWIG_FLAGS += -I" . $my_cwd . "\n"; +print $fh "\nclean_trickify_$name:\n"; +print $fh "\t-make -C \$(SOT_LOCAL_DIR_$name) clean_trickify\n"; +print $fh "\nclean_trickify: clean_trickify_$name\n"; +print $fh "\nnuke_trickify_$name:\n"; +print $fh "\t-make -C \$(SOT_LOCAL_DIR_$name) nuke_trickify\n"; +print $fh "\nnuke_trickify: nuke_trickify_$name\n"; +print $fh "\nrebuild_trickify: $build_dir/$name.$build_type\n"; +print $fh "\nTRICKIFIED_LIBS += $build_dir/$name.$build_type\n"; +print $fh "\nendif\n"; +close($fh); + +open( $fh, ">", "makefile" ) or die "Could not create makefile\n"; +print $fh "\nrebuild_trickify: \n"; +print $fh "\t+$cmdline\n"; +print $fh "\nclean_trickify:\n"; +print $fh "\t-rm -rf build .trick\n"; +print $fh "\t-rm -f S_source.hh\n"; +print $fh "\t-rm -f trickify_obj_list\n"; +print $fh "\t-rm -f trickify_src_list\n"; +print $fh "\t-rm -f trickify_stage_*\n"; +print $fh "\t-rm -f trickify.log\n"; +print $fh "\t-rm -f get_vars.mk\n"; +print $fh "\t-rm -f var_dump.mk\n"; +print $fh "\t-rm -f *_list\n"; +print $fh "\t-rm -f python\n"; +print $fh "\t-rm -f *.a\n"; +print $fh "\t-rm -f *.o\n"; +print $fh "\t-rm -f *.so\n"; +print $fh "\t-rm -rf tmp_build\n"; +print $fh "\t-rm -f full_file\n"; +print $fh "\nnuke_trickify: clean_trickify\n"; +print $fh "\t-rm -f S_overrides_trickify.mk\n"; +print $fh "\t-rm -f *.mk\n"; +close($fh); #Build the S_source.hh -if (!$no_clean_s_source) -{ - print "Building S_source.hh\n" ; - - my @make_s_source ; - my @headers = split ' ', $source_dirs ; - foreach my $ext (@header_ext) - { - find_file_by_ext(\@headers, $ext) ; - push @make_s_source, @files_found ; +if ( !$no_clean_s_source ) { + print "Building S_source.hh\n"; + + my @make_s_source; + my @headers = split ' ', $source_dirs; + foreach my $ext (@header_ext) { + find_file_by_ext( \@headers, $ext ); + push @make_s_source, @files_found; } - push @make_s_source, @lib_deps_header ; + push @make_s_source, @lib_deps_header; - foreach my $excl (@exclude_list) - { - exclude_paths(\@make_s_source, $excl) ; + foreach my $excl (@exclude_list) { + exclude_paths( \@make_s_source, $excl ); } - open (my $fh, ">", "S_source.hh") or die "Could not open S_source.hh\n" ; - foreach my $header (@make_s_source) - { - print $fh "#include \"$header\"\n" ; - } + open( my $fh, ">", "S_source.hh" ) or die "Could not open S_source.hh\n"; + foreach my $header (@make_s_source) { + print $fh "#include \"$header\"\n"; + } } #Build source file list, only if trickifying the entire library -if (!$no_clean_src and $full_build) -{ - print "Building trickify_src_list\n" ; - - my @make_src_list ; - my @sources = split ' ', $source_dirs ; - foreach my $ext (@source_ext) - { - find_file_by_ext(\@sources, $ext) ; - push @make_src_list, @files_found ; +if ( !$no_clean_src and $full_build ) { + print "Building trickify_src_list\n"; + + my @make_src_list; + my @sources = split ' ', $source_dirs; + foreach my $ext (@source_ext) { + find_file_by_ext( \@sources, $ext ); + push @make_src_list, @files_found; } - push @make_src_list, @lib_deps_source ; + push @make_src_list, @lib_deps_source; - foreach my $excl (@exclude_list) - { - exclude_paths(\@make_src_list, $excl) ; + foreach my $excl (@exclude_list) { + exclude_paths( \@make_src_list, $excl ); } - open (my $fh, ">", "trickify_src_list") or die "Could not open trickify_src_list\n" ; - foreach my $source (@make_src_list) - { - print $fh "$source\n" ; + open( my $fh, ">", "trickify_src_list" ) or die "Could not open trickify_src_list\n"; + foreach my $source (@make_src_list) { + print $fh "$source\n"; } } #Build array of source files #We need to read in the file we just wrote to, because there is a no_clean_src option -my @src_files ; -if ($full_build) -{ - open (my $fh, "trickify_src_list") or die "Could not open trickify_src_list: $!" ; - while (my $line = <$fh>) - { - chomp $line ; - push @src_files, $line ; +my @src_files; +if ($full_build) { + open( my $fh, "trickify_src_list" ) or die "Could not open trickify_src_list: $!"; + while ( my $line = <$fh> ) { + chomp $line; + push @src_files, $line; } - close ($fh) ; + close($fh); } -logStage(); #Stage 2 +logStage(); #Stage 2 #Build object files from source file list -if ($full_build) -{ - print "Building object files\n" ; - if($source_make_call eq "") - { +if ($full_build) { + print "Building object files\n"; + if ( $source_make_call eq "" ) { + # Create a makefile for building source files - open (my $fh, ">", "trickify_src.mk") or die "Could not open trickify_src.mk: $!" ; - print $fh "ifneq (\$(TRICKIFY_S_OVERRIDES),)\n" ; - print $fh "\tinclude \$(TRICKIFY_S_OVERRIDES)\n" ; - print $fh "endif\n\n" ; - print $fh "include ${trickify_make_path}/Makefile.common\n\n" ; - print $fh ".SECONDEXPANSION:\n\n" ; + open( my $fh, ">", "trickify_src.mk" ) or die "Could not open trickify_src.mk: $!"; + print $fh "ifneq (\$(TRICKIFY_S_OVERRIDES),)\n"; + print $fh "\tinclude \$(TRICKIFY_S_OVERRIDES)\n"; + print $fh "endif\n\n"; + print $fh "include ${trickify_make_path}/Makefile.common\n\n"; + print $fh ".SECONDEXPANSION:\n\n"; - $ENV{'TRICKIFY_SRC_MAKE_ARGS'} = $source_make_args ; + $ENV{'TRICKIFY_SRC_MAKE_ARGS'} = $source_make_args; my %files_by_ext; - foreach my $src (@src_files) - { - $src =~ /^([\w\W]*\/)([\w\W^\/]*)$/ ; - my $path = $1 ; - my $file = $2 ; + foreach my $src (@src_files) { + $src =~ /^([\w\W]*\/)([\w\W^\/]*)$/; + my $path = $1; + my $file = $2; #create build directory - make_path("build$path") ; + make_path("build$path"); -e "build$path" or die "Could not create dir: build$path, $!\n"; #Determine extension - $src =~ /^([^\s]*)(\.[^\s]*)$/ ; - my $ext = $2 ; - grep { /^\Q$ext\E$/ } @source_ext or die "Invalid extension on $src: $ext\n" ; - push @{$files_by_ext{$ext}}, $1 ; + $src =~ /^([^\s]*)(\.[^\s]*)$/; + my $ext = $2; + grep { /^\Q$ext\E$/ } @source_ext or die "Invalid extension on $src: $ext\n"; + push @{ $files_by_ext{$ext} }, $1; } - foreach my $ext (keys %files_by_ext) - { - print $fh "TRICKIFY_OBJECTS$ext := \\\n" ; - foreach my $src (@{$files_by_ext{$ext}}) - { - print $fh "\t$build_dir/build$src.o \\\n" ; + foreach my $ext ( keys %files_by_ext ) { + print $fh "TRICKIFY_OBJECTS$ext := \\\n"; + foreach my $src ( @{ $files_by_ext{$ext} } ) { + print $fh "\t$build_dir/build$src.o \\\n"; } - if( grep { /^\Q$ext\E$/ } @source_ext_cpp ) - { - print $fh "\n\${TRICKIFY_OBJECTS$ext} : $build_dir/build/%.o : /%$ext | \$\$(dir \$\$@)\n" ; - print $fh "\t\$(TRICK_CXX) \$(TRICKIFY_SRC_MAKE_ARGS) \$(TRICKIFY_CXX_FLAGS) \$(TRICK_CFLAGS) \$(TRICK_SFLAGS) \$(TRICK_CXXFLAGS) \$(TRICK_SYSTEM_CXXFLAGS) -c -o \$@ \$<\n" ; + if ( grep { /^\Q$ext\E$/ } @source_ext_cpp ) { + print $fh "\n\${TRICKIFY_OBJECTS$ext} : $build_dir/build/%.o : /%$ext | \$\$(dir \$\$@)\n"; + print $fh + "\t\$(TRICK_CXX) \$(TRICKIFY_SRC_MAKE_ARGS) \$(TRICKIFY_CXX_FLAGS) \$(TRICK_CFLAGS) \$(TRICK_SFLAGS) \$(TRICK_CXXFLAGS) \$(TRICK_SYSTEM_CXXFLAGS) -c -o \$@ \$<\n"; } - else - { - print $fh "\n\${TRICKIFY_OBJECTS$ext} : $build_dir/build/%.o : /%$ext | \$\$(dir \$\$@)\n" ; - print $fh "\t\$(TRICK_CC) \$(TRICKIFY_SRC_MAKE_ARGS) \$(TRICKIFY_CXX_FLAGS) \$(TRICK_CFLAGS) \$(TRICK_SFLAGS) \$(TRICK_CXXFLAGS) \$(TRICK_SYSTEM_CXXFLAGS) -c -o \$@ \$<\n" ; + else { + print $fh "\n\${TRICKIFY_OBJECTS$ext} : $build_dir/build/%.o : /%$ext | \$\$(dir \$\$@)\n"; + print $fh + "\t\$(TRICK_CC) \$(TRICKIFY_SRC_MAKE_ARGS) \$(TRICKIFY_CXX_FLAGS) \$(TRICK_CFLAGS) \$(TRICK_SFLAGS) \$(TRICK_CXXFLAGS) \$(TRICK_SYSTEM_CXXFLAGS) -c -o \$@ \$<\n"; } } - print $fh "\ntrickify_make:" ; - foreach my $ext (keys %files_by_ext) - { - print $fh " \$(TRICKIFY_OBJECTS$ext)" ; + print $fh "\ntrickify_make:"; + foreach my $ext ( keys %files_by_ext ) { + print $fh " \$(TRICKIFY_OBJECTS$ext)"; } - close ($fh) ; + close($fh); #If an s_overrides.mk is provided we need to build in that dir to preserve relative make paths - if($s_overrides_dir ne "") - { - chdir Cwd::abs_path($s_overrides_dir) or die "Error changing to s_overrides directory: $s_overrides_dir\n" ; + if ( $s_overrides_dir ne "" ) { + chdir Cwd::abs_path($s_overrides_dir) or die "Error changing to s_overrides directory: $s_overrides_dir\n"; } - my $cmd = "make trickify_make -f $build_dir/trickify_src.mk" ; - my $cmd_ret = `$cmd 2>&1` ; - if($cmd_ret ne "") - { - print "$cmd_ret" ; + my $cmd = "make trickify_make -f $build_dir/trickify_src.mk"; + my $cmd_ret = `$cmd 2>&1`; + if ( $cmd_ret ne "" ) { + print "$cmd_ret"; } - if($? != 0) - { - die $? ; + if ( $? != 0 ) { + die $?; } - chdir Cwd::abs_path($build_dir) or die "Error changing to build directory: $build_dir\n" ; + chdir Cwd::abs_path($build_dir) or die "Error changing to build directory: $build_dir\n"; } - else - { - print(`$source_make_call`) ; - if($? != 0) - { - die $? ; + else { + print(`$source_make_call`); + if ( $? != 0 ) { + die $?; } } } #Build object file list, only if trickifying the entire library -if(!$no_clean_obj and $full_build) -{ - print "Building trickify_obj_list\n" ; +if ( !$no_clean_obj and $full_build ) { + print "Building trickify_obj_list\n"; + #Create list of source file names without dirs and extensions - my @src_files_base ; - foreach my $src (@src_files) - { - $src =~ s/\..*$// ; - push @src_files_base, basename($src) ; + my @src_files_base; + foreach my $src (@src_files) { + $src =~ s/\..*$//; + push @src_files_base, basename($src); } #Create a list of all .o files under build - my @make_obj_list ; - my @build_dir = getcwd ; - find_file_by_ext(\@build_dir, ".o") ; - push @make_obj_list, @files_found ; - - open (my $fh, ">", "trickify_obj_list") or die "Could not open trickify_obj_list\n" ; - foreach my $obj (@make_obj_list) - { + my @make_obj_list; + my @build_dir = getcwd; + find_file_by_ext( \@build_dir, ".o" ); + push @make_obj_list, @files_found; + + open( my $fh, ">", "trickify_obj_list" ) or die "Could not open trickify_obj_list\n"; + foreach my $obj (@make_obj_list) { + #remove the dir and extension - $obj =~ /^(.+?)\Q.o\E$/ ; - my $raw_filename = $1 ; - $raw_filename = basename($raw_filename) ; - + $obj =~ /^(.+?)\Q.o\E$/; + my $raw_filename = $1; + $raw_filename = basename($raw_filename); + #only write .o that have a matching source file #this ensures we don't grab swig and icg .o artifacts twice, those are pulled in later - my @is_present = grep (/\Q$raw_filename\E/, @src_files_base) ; - if(@is_present ne 0) - { - print $fh "$obj\n" ; + my @is_present = grep ( /\Q$raw_filename\E/, @src_files_base ); + if ( @is_present ne 0 ) { + print $fh "$obj\n"; } - } + } } -logStage(); #Stage 3 +logStage(); #Stage 3 #Build trickify call -print "Begin Trickification...\n" ; -if($s_overrides_dir ne "") -{ - chdir Cwd::abs_path($s_overrides_dir) or die "Error changing to s_overrides directory: $s_overrides_dir\n" ; - dump_makefile_vars($s_overrides, $build_dir, \%SHELL_ENV, ("TRICKIFY_BUILD_TYPE", "TRICKIFY_OBJECT_NAME", "TRICKIFY_PYTHON_DIR", "TRICK_CFLAGS", "TRICK_CXXFLAGS", "TRICK_SYSTEM_SWIG_CFLAGS", "TRICK_SWIG_CFLAGS")) ; - chdir Cwd::abs_path($build_dir) or die "Error changing to build directory: $build_dir\n" ; - $ENV{"TRICKIFY_MAKE_DUMP"} = Cwd::abs_path("var_dump.mk") ; -} -my $trickify_make_call = "make $trickify_make_args -f $trickify_make_path/trickify.mk trickify" ; -my $cmd_ret = `$trickify_make_call 2>&1` ; -my $cmd_exit_code = $? ; -if($cmd_ret ne "") -{ - print "$cmd_ret" ; -} - -if($cmd_exit_code != 0) -{ - die $cmd_exit_code ; -} - -logStage(); #Stage 4 - +print "Begin Trickification...\n"; +if ( $s_overrides_dir ne "" ) { + chdir Cwd::abs_path($s_overrides_dir) or die "Error changing to s_overrides directory: $s_overrides_dir\n"; + dump_makefile_vars( + $s_overrides, + $build_dir, + \%SHELL_ENV, + $build_dir, + ( + "TRICKIFY_BUILD_TYPE", "TRICKIFY_OBJECT_NAME", "TRICKIFY_PYTHON_DIR", "TRICK_CFLAGS", + "TRICK_CXXFLAGS", "TRICK_SFLAGS", "TRICK_SYSTEM_CXXFLAGS", "TRICK_SYSTEM_SWIG_CFLAGS", + "TRICK_SWIG_CFLAGS", "TRICK_EXCLUDE" + ) + ); + chdir Cwd::abs_path($build_dir) or die "Error changing to build directory: $build_dir\n"; + $ENV{"TRICKIFY_MAKE_DUMP"} = Cwd::abs_path("var_dump.mk"); +} +my $trickify_make_call = "make $trickify_make_args -f $trickify_make_path/trickify.mk trickify"; +my $cmd_ret = `$trickify_make_call 2>&1`; +my $cmd_exit_code = $?; +if ( $cmd_ret ne "" ) { + print "$cmd_ret"; +} + +if ( $cmd_exit_code != 0 ) { + die $cmd_exit_code; +} + +logStage(); #Stage 4 #The full file list is dumped as one line. We need to clean it up (don't want to do that in bash lol) -my @full_file_list ; -if (-e "full_file") -{ - open ($fh, '<', "full_file") or die "Could not open full_file: $!" ; - my $line = <$fh> ; - chomp $line ; - @full_file_list = split ' ', $line ; - close ($fh) ; - print `rm full_file` ; - +my @full_file_list; +if ( -e "full_file" ) { + open( $fh, '<', "full_file" ) or die "Could not open full_file: $!"; + my $line = <$fh>; + chomp $line; + @full_file_list = split ' ', $line; + close($fh); + print `rm full_file`; #py and io link lists use relative paths (start with build/) #obj file list uses full file paths #need to make them similar - @full_file_list = map - { - my $ret = $_ ; - if( $_ !~ /^\Qbuild\/\E/ ) - { - /^(.*)(\Qbuild\/\E.*)$/ ; - $ret = $2 ; + @full_file_list = map { + my $ret = $_; + if ( $_ !~ /^\Qbuild\/\E/ ) { + /^(.*)(\Qbuild\/\E.*)$/; + $ret = $2; } - $ret ; - } - (@full_file_list) ; + $ret; + } (@full_file_list); - open ($fh, '>', "full_file_list") or die "Could not open full_file_list: $!" ; - map { print $fh "$_\n" } @full_file_list ; - close ($fh) ; + open( $fh, '>', "full_file_list" ) or die "Could not open full_file_list: $!"; + map { print $fh "$_\n" } @full_file_list; + close($fh); } #Generate dependency list @@ -652,75 +586,69 @@ if (-e "full_file") #All explicity declared files are included, along with all their non-trick/system #include #We piggyback off of ICG's lists to track all #include in the lib my %trickify_dep_list; -my @dep_lists = ("trickify_src_list", "build/ICG_processed", "build/ICG_no_found"); -foreach my $list (@dep_lists) -{ - open ($fh, $list) or die "Could not open $list: $!" ; - while (my $line = <$fh>) - { - chomp $line ; - if($line !~ /\QS_source.hh\E$/) - { - $trickify_dep_list{$line} = 1 ; +my @dep_lists = ( "trickify_src_list", "build/ICG_processed", "build/ICG_no_found" ); +foreach my $list (@dep_lists) { + open( $fh, $list ) or die "Could not open $list: $!"; + while ( my $line = <$fh> ) { + chomp $line; + if ( $line !~ /\QS_source.hh\E$/ ) { + $trickify_dep_list{$line} = 1; } } - close ($fh) ; -} - -open ($fh, '>', "trickify_dep.mk") or die "Could not open trickify_dep.mk: $!" ; -print $fh "TDMK_LOCAL_DIR_$name := \$(abspath \$(dir \$(lastword \$(MAKEFILE_LIST))))\n\n" ; -my $dep_rule = "$build_dir/$name.$build_type:\\\n" ; -$dep_rule .= (join "\n", map { "\t$_\\" } (sort keys %trickify_dep_list)) . "\n" ; -print $fh "ifeq (\$(TRICKIFY_AUTO_REBUILD), 0)\n" ; -print $fh $dep_rule ; -print $fh "\n\t\@echo Trickify rebuild disabled.\n" ; -print $fh "else\n" ; -print $fh "\$(eval \\\n$dep_rule;\\" ; -print $fh "\n\tmake -C \$(TDMK_LOCAL_DIR_$name) rebuild_trickify\\\n)\n" ; -print $fh "endif\n" ; -close ($fh) ; - -open ($fh, '>', "trickify_dep_list") or die "Could not open trickify_dep_list: $!" ; -print $fh (join "\n", (sort keys %trickify_dep_list)) ; -close ($fh) ; + close($fh); +} + +open( $fh, '>', "trickify_dep.mk" ) or die "Could not open trickify_dep.mk: $!"; +print $fh "TDMK_LOCAL_DIR_$name := \$(abspath \$(dir \$(lastword \$(MAKEFILE_LIST))))\n\n"; +my $dep_rule = "$build_dir/$name.$build_type:\\\n"; +$dep_rule .= ( join "\n", map { "\t$_\\" } ( sort keys %trickify_dep_list ) ) . "\n"; +print $fh "ifeq (\$(TRICKIFY_AUTO_REBUILD), 0)\n"; +print $fh $dep_rule; +print $fh "\n\t\@echo Trickify rebuild disabled.\n"; +print $fh "else\n"; +print $fh "\$(eval \\\n$dep_rule;\\"; +print $fh "\n\tmake -C \$(TDMK_LOCAL_DIR_$name) rebuild_trickify\\\n)\n"; +print $fh "endif\n"; +close($fh); + +open( $fh, '>', "trickify_dep_list" ) or die "Could not open trickify_dep_list: $!"; +print $fh ( join "\n", ( sort keys %trickify_dep_list ) ); +close($fh); #look for files outside the selected dirs/s_define filter -my @extra_file_list = grep -{ - my $ret = 0 ; - s/^\Qbuild\E//; #strip the leading build from the file path - my $file = $_ ; - my @valid_dirs = ((split ' ', $s_define_filter), (split ' ', $source_dirs)) ; #all paths provided by the user for source +my @extra_file_list = grep { + my $ret = 0; + s/^\Qbuild\E//; #strip the leading build from the file path + my $file = $_; + my @valid_dirs = + ( ( split ' ', $s_define_filter ), ( split ' ', $source_dirs ) ); #all paths provided by the user for source #if the file does not start with a s_define filter or source dir - if( (grep { $file =~ /^\Q$_\E/ } (@valid_dirs)) == 0 ) - { - $ret = 1 ; + if ( ( grep { $file =~ /^\Q$_\E/ } (@valid_dirs) ) == 0 ) { + $ret = 1; } #if the file starts with an excluded path - if( grep { $file =~ /^\Q$_\E/ } (@exclude_list) ) - { - $ret = 1 ; + if ( grep { $file =~ /^\Q$_\E/ } (@exclude_list) ) { + $ret = 1; } $ret; -} -(sort keys %trickify_dep_list) ; +} ( sort keys %trickify_dep_list ); -open ($fh, '>', "extra_file_list") or die "Could not open extra_file_list: $!" ; -map { print $fh "$_\n" } @extra_file_list ; -close ($fh) ; +open( $fh, '>', "extra_file_list" ) or die "Could not open extra_file_list: $!"; +map { print $fh "$_\n" } @extra_file_list; +close($fh); #Print warnings and additional info -if ( @extra_file_list ) -{ - printc("yellow", "WARNING: Extra files were processed to build trickified library. Check extra_file_list in the build directory.\n") ; +if (@extra_file_list) { + printc( "yellow", + "WARNING: Extra files were processed to build trickified library. Check extra_file_list in the build directory.\n" + ); } -if($debug) { - print - "TRICKIFY BUILD INFO: +if ($debug) { + print "TRICKIFY BUILD INFO: source_dirs = $source_dirs source_make_call = $source_make_call trickify_make_args = $trickify_make_args @@ -730,8 +658,8 @@ if($debug) { name = $name build_type = $build_type trick_home = $trick_home - TRICKIFY_CXX_FLAGS = $ENV{'TRICKIFY_CXX_FLAGS'}\n" ; + TRICKIFY_CXX_FLAGS = $ENV{'TRICKIFY_CXX_FLAGS'}\n"; } -system("rm trickify_stage*") ; -printc("green", "Trickification complete!\n") ; +system("rm trickify_stage*"); +printc( "green", "Trickification complete!\n" ); diff --git a/libexec/trick/configuration_processor b/libexec/trick/configuration_processor index b3a130b2d..3a88d95c0 100755 --- a/libexec/trick/configuration_processor +++ b/libexec/trick/configuration_processor @@ -1,111 +1,108 @@ #! /usr/bin/perl -use File::Basename ; -use Cwd ; -use strict ; -use Getopt::Long ; -use Pod::Usage ; -use Pod::Text ; +use File::Basename; +use Cwd; +use strict; +use Getopt::Long; +use Pod::Usage; +use Pod::Text; use Cwd 'abs_path'; use FindBin qw($RealBin); -use lib "$RealBin/pm" ; - -use parse_s_define ; -use gte ; -use s_source ; -use trick_print ; -use trick_version ; -use get_paths ; -use verbose_build ; - -my %sim ; -my $cwd = cwd(); -my $verbose_build = verbose_build() ; -my @ext_lib_paths = get_paths( "TRICK_EXT_LIB_DIRS" ) ; -my @ext_lib_paths_overrides = get_paths( "TRICK_EXT_LIB_DIRS_OVERRIDES" ) ; +use lib "$RealBin/pm"; + +use parse_s_define; +use gte; +use s_source; +use trick_print; +use trick_version; +use get_paths; +use verbose_build; + +my %sim; +my $cwd = cwd(); +my $verbose_build = verbose_build(); +my @ext_lib_paths = get_paths("TRICK_EXT_LIB_DIRS"); +my @ext_lib_paths_overrides = get_paths("TRICK_EXT_LIB_DIRS_OVERRIDES"); # override the print format for help message -*Pod::Text::seq_i = sub { return "" . $_[1] . "" } ; +*Pod::Text::seq_i = sub { return "" . $_[1] . "" }; # set default verbose level -$sim{args}{v} = 2 ; -$sim{args}{o} = "build/CP_out" ; -$sim{args}{p} = 1 ; +$sim{args}{v} = 2; +$sim{args}{o} = "$ENV{TRICK_BUILD_DIR}build/CP_out"; +$sim{args}{p} = 1; #-------------------------------------------------------------- # Process command line arguments -Getopt::Long::Configure ("bundling"); -GetOptions ( "no-python|p" => sub { $sim{args}{p} = 0 } , - "debug|g" => sub { $sim{args}{v} = 3 ; } , - "help|h|?" => \$sim{args}{h} , - "outfile|o=s" => \$sim{args}{o} , - "t" => \$sim{args}{t} , - "verbose|v=i" => \$sim{args}{v} - ) or pod2usage(1) ; - -pod2usage(1) if $sim{args}{h} ; +Getopt::Long::Configure("bundling"); +GetOptions( + "no-python|p" => sub { $sim{args}{p} = 0 }, + "debug|g" => sub { $sim{args}{v} = 3; }, + "help|h|?" => \$sim{args}{h}, + "outfile|o=s" => \$sim{args}{o}, + "t" => \$sim{args}{t}, + "verbose|v=i" => \$sim{args}{v} +) or pod2usage(1); + +pod2usage(1) if $sim{args}{h}; # Get Trick version -my ($version, $thread) = get_trick_version() ; -$thread =~ s/\d+\.// ; - -if ( ! -e "build" ) { - mkdir "build", 0755 ; -} - -local *OUTFILE ; -open OUTFILE , ">$sim{args}{o}" or warn "CP cannot open $sim{args}{o} for writing\n" ; -$sim{fh} = *OUTFILE ; -print OUTFILE "Output for $0 version $version-$thread at " . localtime() . "\n\n" ; +my ( $version, $thread ) = get_trick_version(); +$thread =~ s/\d+\.//; +local *OUTFILE; +open OUTFILE, ">$sim{args}{o}" or warn "CP cannot open $sim{args}{o} for writing\n"; +$sim{fh} = *OUTFILE; +print OUTFILE "Output for $0 version $version-$thread at " . localtime() . "\n\n"; # if no python is specified, turn off the python InputProcessor sim_object in S_define. if ( $sim{args}{p} == 0 ) { - $ENV{TRICK_SYSTEM_SFLAGS} .= " -DTRICK_NO_INPUTPROCESSOR" ; + $ENV{TRICK_SYSTEM_SFLAGS} .= " -DTRICK_NO_INPUTPROCESSOR"; } #-------------------------------------------------------------- # Parse the S_define file -trick_print($sim{fh}, "Parsing " , "title_blue" , $sim{args}{v}) ; -trick_print($sim{fh}, "S_define" , "title_white" , $sim{args}{v}) ; -trick_print($sim{fh}, "\n" , "title_white" , $sim{args}{v}) if ( $sim{args}{v} != 1 ) ; +trick_print( $sim{fh}, "Parsing ", "title_blue", $sim{args}{v} ); +trick_print( $sim{fh}, "S_define", "title_white", $sim{args}{v} ); +trick_print( $sim{fh}, "\n", "title_white", $sim{args}{v} ) if ( $sim{args}{v} != 1 ); -parse_s_define(\%sim) ; +parse_s_define( \%sim ); -trick_print( $sim{fh}, "Finished " , "normal_blue" , $ sim{args}{v} ) ; -trick_print( $sim{fh}, "S_define\n" , "normal_white" , $ sim{args}{v} ) ; +trick_print( $sim{fh}, "Finished ", "normal_blue", $sim{args}{v} ); +trick_print( $sim{fh}, "S_define\n", "normal_white", $sim{args}{v} ); #-------------------------------------------------------------- # Make S_source.c -trick_print($sim{fh}, "Writing ", "title_blue", $sim{args}{v}); -trick_print($sim{fh}, "S_source.c\n", "title_white", $sim{args}{v}); -s_source( \%sim ) ; +trick_print( $sim{fh}, "Writing ", "title_blue", $sim{args}{v} ); +trick_print( $sim{fh}, "S_source.c\n", "title_white", $sim{args}{v} ); +s_source( \%sim ); #-------------------------------------------------------------- # close -chdir ($cwd) ; -close OUTFILE ; +chdir($cwd); +close OUTFILE; #-------------------------------------------------------------- # Write out the library dependencies found in the S_define file. -open LIBDEP, ">build/S_define.lib_deps" ; -foreach my $file ( @{$sim{mis_entry_files}} ) { +open LIBDEP, ">$ENV{TRICK_BUILD_DIR}build/S_define.lib_deps"; +foreach my $file ( @{ $sim{mis_entry_files} } ) { if ( $file ne "" ) { - $file = abs_path(dirname($file)) . "/" . basename($file) ; + $file = abs_path( dirname($file) ) . "/" . basename($file); if ( my $path = get_containing_path( $file, @ext_lib_paths ) ) { if ( get_containing_path( $file, @ext_lib_paths_overrides ) eq 0 ) { - print "Dep Skip TRICK_EXT_LIB_DIRS: $path" . substr($file, length $path) . "\n" if $verbose_build ; - next ; + print "Dep Skip TRICK_EXT_LIB_DIRS: $path" . substr( $file, length $path ) . "\n" + if $verbose_build; + next; } } - print LIBDEP "$file\n" ; + print LIBDEP "$file\n"; } } -close LIBDEP ; +close LIBDEP; ################################################################################ # END MAIN diff --git a/libexec/trick/convert_swig b/libexec/trick/convert_swig index 77de2902b..6fb049c6d 100755 --- a/libexec/trick/convert_swig +++ b/libexec/trick/convert_swig @@ -139,7 +139,7 @@ if ( "$ENV{'TRICK_CFLAGS'} $ENV{'TRICK_CXXFLAGS'}" !~ /DTRICK_VER=/ ) { } if ( scalar @ARGV == 0 ) { - my ($s_library_swig) = "build/S_library_swig"; + my ($s_library_swig) = "$ENV{TRICK_BUILD_DIR}build/S_library_swig"; open FILE_LIST, $s_library_swig or die "Could not open $s_library_swig"; while () { chomp; @@ -151,7 +151,7 @@ if ( scalar @ARGV == 0 ) { $base_file =~ s/\.[^\.]+$//; $swig_dir = dirname($f); - $swig_dir = "build/$swig_dir"; + $swig_dir = "$ENV{TRICK_BUILD_DIR}build/$swig_dir"; $swig_file = "$swig_dir/${base_file}_py.i"; #print "$swig_file\n" ; @@ -195,7 +195,6 @@ process_file(); sub process_file() { ## Foreach out_of_date header file, generate a SWIG interface file. - foreach my $f ( keys %out_of_date ) { my @class_names; @@ -284,7 +283,7 @@ sub process_file() { next outer; } } - $file_name = "build" . $file_name; + $file_name = "$ENV{TRICK_BUILD_DIR}build" . $file_name; $file_name =~ s/\.[^\.]+?$/\_py.i/; $contents .= "\%import \"$file_name\"\n"; } @@ -301,14 +300,8 @@ sub process_file() { my $md5_sum = md5_hex($f); - my ($out_dir) = dirname($f); - $out_dir = "build$out_dir"; - - my $out_file; - $out_file = basename($f); - $out_file =~ s/(\.h|\.H|\.hh|\.h\+\+|\.hxx|\.hpp)$/_py\.i/; - - $out_file = "$out_dir/${out_file}"; + my $out_file = "$ENV{TRICK_BUILD_DIR}build" . get_dot_i_name($f); + my ($out_dir) = dirname($out_file); if ( !-e $out_dir ) { make_path($out_dir); @@ -370,7 +363,6 @@ sub process_file() { print "Writing $out_file\n" if not verbose_build(); } - } sub usage() { @@ -902,4 +894,21 @@ sub process_typedef_const_struct($$$$) { } +## ================================================================================ +## get_dot_i_name +## +## Synopsis +## +## Takes the path to a header file. Returns the path formatted as a SWIG .i file. +## + +sub get_dot_i_name($) { + my ($path) = @_; + + my ($i_dir) = dirname($path); + my $i_file = basename($path); + $i_file =~ s/(\.h|\.H|\.hh|\.h\+\+|\.hxx|\.hpp)$/_py\.i/; + $i_file = "$i_dir/${i_file}"; +} + __END__ diff --git a/libexec/trick/create_top_dot_i b/libexec/trick/create_top_dot_i index 7b0b8310f..bb3a6e06e 100755 --- a/libexec/trick/create_top_dot_i +++ b/libexec/trick/create_top_dot_i @@ -2,19 +2,29 @@ import os -with open('build/CP_instances') as cp_instances: - with open('build/top.i', 'w') as top: +try: + trick_build_dir = os.environ["TRICK_BUILD_DIR"] +except KeyError: + trick_build_dir = "" + +with open(trick_build_dir + "build/CP_instances") as cp_instances: + with open(trick_build_dir + "build/top.i", "w") as top: path = os.path.abspath(os.getcwd()) - instances = ''.join(cp_instances.readlines()) + instances = "".join(cp_instances.readlines()) top.write( - '%module top\n' - '\n' - '%{\n' - '#include "../S_source.hh"\n' - '\n' + - instances + '\n' - '%}\n' - '\n' - '%import "build' + path + '/S_source_py.i"\n' - '\n' + - instances) + "%module top\n" + "\n" + "%{\n" + '#include "../S_source.hh"\n' + "\n" + instances + "\n" + "%}\n" + "\n" + '%import "' + + trick_build_dir + + "build" + + path + + "/" + + trick_build_dir + + 'S_source_py.i"\n' + "\n" + instances + ) diff --git a/libexec/trick/make_makefile_src b/libexec/trick/make_makefile_src index 18002568f..d226114e5 100755 --- a/libexec/trick/make_makefile_src +++ b/libexec/trick/make_makefile_src @@ -1,183 +1,197 @@ #!/usr/bin/perl use FindBin qw($RealBin); -use lib "$RealBin/pm" ; +use lib "$RealBin/pm"; -use strict ; -use File::Basename ; -use Cwd ; +use strict; +use File::Basename; +use Cwd; use Cwd 'abs_path'; -use trick_version ; -use get_lib_deps ; -use verbose_build ; - -my %processed_files ; -my %non_lib_processed_files ; -my $any_deps_changed = 0 ; -my $verbose_build = verbose_build() ; +use trick_version; +use get_lib_deps; +use verbose_build; + +my %processed_files; +my %non_lib_processed_files; +my $any_deps_changed = 0; +my $verbose_build = verbose_build(); + +my $trick_build_dir = "./"; +if ( exists $ENV{'TRICK_BUILD_DIR'} ) { + $trick_build_dir = $ENV{'TRICK_BUILD_DIR'}; +} sub exist_lib_deps(@) { - my (@files_to_process) = @_ ; - foreach my $l ( @files_to_process ) { - next if ( $l eq "" ) ; - next if ( $l =~ /^-|\.a$/ ) ; - next if ( ! -e $l ) ; - my ( $file, $dir, $suffix) = fileparse($l, qr/\.[^.]*/) ; - my ($lib_dep_file_name) = "build$dir${file}${suffix}.lib_deps" ; - if ( ! -e $lib_dep_file_name ) { - $any_deps_changed = 1 ; - print "New Dep $l\n" ; - return 1 ; + my (@files_to_process) = @_; + foreach my $l (@files_to_process) { + next if ( $l eq "" ); + next if ( $l =~ /^-|\.a$/ ); + next if ( !-e $l ); + my ( $file, $dir, $suffix ) = fileparse( $l, qr/\.[^.]*/ ); + my ($lib_dep_file_name) = "$ENV{TRICK_BUILD_DIR}build/${dir}${file}${suffix}.lib_deps"; + if ( !-e $lib_dep_file_name ) { + $any_deps_changed = 1; + print "New Dep $l\n"; + return 1; } } - return 0 ; + return 0; } sub read_lib_deps($@) { - my ($indent , @files_to_process) = @_ ; - foreach my $l ( @files_to_process ) { - next if ( $l eq "" ) ; - if ( ! exists $processed_files{$l} ) { - $processed_files{$l} = 1 ; - next if ( $l =~ /^-|\.a$/ ) ; - $non_lib_processed_files{$l} = 1 ; - my ( $file, $dir, $suffix) = fileparse($l, qr/\.[^.]*/) ; - my ($lib_dep_file_name) = "build$dir${file}${suffix}.lib_deps" ; + my ( $indent, @files_to_process ) = @_; + foreach my $l (@files_to_process) { + next if ( $l eq "" ); + if ( !exists $processed_files{$l} ) { + $processed_files{$l} = 1; + next if ( $l =~ /^-|\.a$/ ); + $non_lib_processed_files{$l} = 1; + my ( $file, $dir, $suffix ) = fileparse( $l, qr/\.[^.]*/ ); + my ($lib_dep_file_name) = "$ENV{TRICK_BUILD_DIR}build/${dir}${file}${suffix}.lib_deps"; if ( -e $lib_dep_file_name ) { - open FH, "$lib_dep_file_name" or die 'cannot open $lib_dep_file_name' ; - my (@all_lines) = ; - close FH ; - chomp @all_lines ; - read_lib_deps($indent + 1 , @all_lines) ; - } else { - print "DepTracing " , " " x $indent, "$l\n" ; + open FH, "$lib_dep_file_name" or die 'cannot open $lib_dep_file_name'; + my (@all_lines) = ; + close FH; + chomp @all_lines; + read_lib_deps( $indent + 1, @all_lines ); + } + else { + print "DepTracing ", " " x $indent, "$l\n"; if ( -e $l ) { - my $deps_changed ; - my @resolved_files ; - ($deps_changed , @resolved_files) = write_lib_deps($l) ; - $any_deps_changed |= $deps_changed ; - read_lib_deps($indent + 1 , @resolved_files) ; + my $deps_changed; + my @resolved_files; + ( $deps_changed, @resolved_files ) = write_lib_deps($l); + $any_deps_changed |= $deps_changed; + read_lib_deps( $indent + 1, @resolved_files ); } } - } elsif ( $verbose_build ) { - print "Skipping Previously processed file \"$l\"\n" ; + } + elsif ($verbose_build) { + print "Skipping Previously processed file \"$l\"\n"; } } } # Update any possibly out of date lib_dep files if ( scalar @ARGV ) { + # Arguments are all files (headers and source) that are newer than the makefile. # Keep track if any dependencies changed - for my $f ( @ARGV ) { + for my $f (@ARGV) { + # Filter out Makefile_io_src_deps, Makefie_io_src, and S_source.hh from the argument list. # These are dependencies in the makefile. # S_source.hh will be passed in as a full path again if the file has changed. - next if ( $f eq "build/Makefile_src_deps" or $f eq "build/Makefile_io_src" or $f eq "S_source.hh") ; - my $deps_changed ; - my @resolved_files ; - print "DepTracing " , "$f\n" ; - ($deps_changed , @resolved_files ) = write_lib_deps($f) ; - $any_deps_changed |= $deps_changed ; + next + if ( $f eq "$ENV{TRICK_BUILD_DIR}build/Makefile_src_deps" + or $f eq "$ENV{TRICK_BUILD_DIR}build/Makefile_io_src" + or $f eq "$ENV{TRICK_BUILD_DIR}S_source.hh" ); + my $deps_changed; + my @resolved_files; + print "DepTracing ", "$f\n"; + ( $deps_changed, @resolved_files ) = write_lib_deps($f); + $any_deps_changed |= $deps_changed; } -} else { +} +else { # no arguments mean we are calling this for the first time. Always make makefile - $any_deps_changed = 1 ; + $any_deps_changed = 1; } -if ( ! -e "build/Makefile_src") { - $any_deps_changed = 1 ; +if ( !-e "$ENV{TRICK_BUILD_DIR}build/Makefile_src" ) { + $any_deps_changed = 1; } # Read in dependency tree starting at the roots. The dependency tree starts with all of the # header files ICG processed and the lib deps listed in the S_define file. -open FILE, "build/ICG_processed" or die 'cannot open build/ICG_processed' ; -my (@top_file_names) = ; -close FILE ; -open FILE, "build/ICG_no_found" or die 'cannot open build/ICG_no_found' ; -my (@ICG_no_file_names) = ; -close FILE ; -push @top_file_names , @ICG_no_file_names ; -open FILE, "build/S_define.lib_deps" or die 'cannot open build/S_define.lib_deps' ; -my (@s_define_lib_deps) = ; -close FILE ; -push @top_file_names , @s_define_lib_deps ; -chomp @top_file_names ; +open FILE, "$ENV{TRICK_BUILD_DIR}build/ICG_processed" or die "cannot open $ENV{TRICK_BUILD_DIR}build/ICG_processed"; +my (@top_file_names) = ; +close FILE; +open FILE, "$ENV{TRICK_BUILD_DIR}build/ICG_no_found" or die "cannot open $ENV{TRICK_BUILD_DIR}build/ICG_no_found"; +my (@ICG_no_file_names) = ; +close FILE; +push @top_file_names, @ICG_no_file_names; +open FILE, "$ENV{TRICK_BUILD_DIR}build/S_define.lib_deps" + or die "cannot open $ENV{TRICK_BUILD_DIR}build/S_define.lib_deps"; +my (@s_define_lib_deps) = ; +close FILE; +push @top_file_names, @s_define_lib_deps; +chomp @top_file_names; # See if any depenendices lack a .lib_deps file. If it does we need to continue -$any_deps_changed |= exist_lib_deps(@top_file_names) ; +$any_deps_changed |= exist_lib_deps(@top_file_names); # if no dependencies have changed, "touch" Makefile_src and exit if ( $any_deps_changed == 0 ) { - utime(undef, undef, "build/Makefile_src") ; - exit ; + utime( undef, undef, "$ENV{TRICK_BUILD_DIR}build/Makefile_src" ); + exit; } # We are here if dependencies have changed or we're running for the first time. # Read in all of the lib_dep files. # read_lib_deps wil create lib_dep files that don't exist and read them in too. -read_lib_deps(0, @top_file_names) ; +read_lib_deps( 0, @top_file_names ); #print map {"$_\n"} (sort keys %processed_files) ; -my ($n , $f , $k , $i , $m); -my @all_cfly_files ; -my @all_read_only_libs ; -my @all_compile_libs ; -my %files_by_dir ; +my ( $n, $f, $k, $i, $m ); +my @all_cfly_files; +my @all_read_only_libs; +my @all_compile_libs; +my %files_by_dir; -@all_cfly_files = keys %processed_files ; -@all_read_only_libs = sort (grep /^-/ , @all_cfly_files) ; -@all_compile_libs = grep /\.a$/ , @all_cfly_files ; -@all_compile_libs = sort (grep !/trick_source/ , @all_compile_libs) ; -@all_cfly_files = sort (grep !/^-|trick_source|a$/ , @all_cfly_files) ; +@all_cfly_files = keys %processed_files; +@all_read_only_libs = sort ( grep /^-/, @all_cfly_files ); +@all_compile_libs = grep /\.a$/, @all_cfly_files; +@all_compile_libs = sort ( grep !/trick_source/, @all_compile_libs ); +@all_cfly_files = sort ( grep !/^-|trick_source|a$/, @all_cfly_files ); sub add_file($) { - my ($name, $path, $extension) = fileparse($_[0], qr/\.[^.]*/) ; - push @{$files_by_dir{$path}{$extension}} , $name ; + my ( $name, $path, $extension ) = fileparse( $_[0], qr/\.[^.]*/ ); + push @{ $files_by_dir{$path}{$extension} }, $name; } sub add_files_in_directory($) { - opendir THISDIR, "$_[0]" or die "Could not open $_[0]" ; - my @files = grep !/^\./ , readdir THISDIR ; - foreach ( @files ) { - add_file($_[0] . "/" . $_) ; + opendir THISDIR, "$_[0]" or die "Could not open $_[0]"; + my @files = grep !/^\./, readdir THISDIR; + foreach (@files) { + add_file( $_[0] . "/" . $_ ); } - closedir THISDIR ; + closedir THISDIR; } # split off files by directory -foreach ( @all_cfly_files ) { +foreach (@all_cfly_files) { add_file($_); } # get all of the files required by compiled libraries # compile all files as normal files, we're not going to make a library anymore. -foreach ( @all_compile_libs ) { - my $path = abs_path(dirname($_)); - add_files_in_directory($path) ; - $path .= "/src" ; - add_files_in_directory($path) if -e "$path" ; +foreach (@all_compile_libs) { + my $path = abs_path( dirname($_) ); + add_files_in_directory($path); + $path .= "/src"; + add_files_in_directory($path) if -e "$path"; } # sort and weed out duplicate files foreach my $directory ( keys %files_by_dir ) { - my %temp_hash ; - foreach my $extension ( keys %{$files_by_dir{$directory}} ) { - undef %temp_hash ; - @{$files_by_dir{$directory}{$extension}} = sort grep ++$temp_hash{$_} < 2, @{$files_by_dir{$directory}{$extension}} ; + my %temp_hash; + foreach my $extension ( keys %{ $files_by_dir{$directory} } ) { + undef %temp_hash; + @{ $files_by_dir{$directory}{$extension} } = sort grep ++$temp_hash{$_} < 2, + @{ $files_by_dir{$directory}{$extension} }; } } -my $wd = abs_path(cwd()) ; -my $dt = localtime(); -my ($trick_ver) = get_trick_version() ; -chomp $trick_ver ; +my $wd = abs_path( cwd() ); +my $dt = localtime(); +my ($trick_ver) = get_trick_version(); +chomp $trick_ver; -open MAKEFILE , ">build/Makefile_src" or return ; +open MAKEFILE, ">$ENV{TRICK_BUILD_DIR}build/Makefile_src" or return; -print MAKEFILE -"################################################################################ +print MAKEFILE "################################################################################ # Makefile: # This is a makefile for maintaining the # '$wd' @@ -200,59 +214,60 @@ ifndef TRICK_VERBOSE_BUILD PRINT_SIE = \$(info \$(call COLOR,Writing) \$@) endif -S_MAIN = S_main_\${TRICK_HOST_CPU}.exe +S_MAIN = $ENV{TRICK_BUILD_DIR}S_main_\${TRICK_HOST_CPU}.exe ifeq (\$(MAKECMDGOALS), test) TRICK_HOST_CPU := \$(shell \$(TRICK_HOME)/bin/trick-gte TRICK_HOST_CPU)_test - S_MAIN = T_main_\${TRICK_HOST_CPU}.exe + S_MAIN = $ENV{TRICK_BUILD_DIR}T_main_\${TRICK_HOST_CPU}.exe endif # S_OBJECTS ==================================================================== -S_OBJECTS = build/S_source.o +S_OBJECTS = $ENV{TRICK_BUILD_DIR}build/S_source.o -build/S_source.o: build/S_source.cpp | build/S_source.d +$ENV{TRICK_BUILD_DIR}build/S_source.o: $ENV{TRICK_BUILD_DIR}build/S_source.cpp | $ENV{TRICK_BUILD_DIR}build/S_source.d \t\$(PRINT_COMPILE) \t\$(call ECHO_AND_LOG,\$(TRICK_CXX) \$(TRICK_CXXFLAGS) \$(TRICK_SYSTEM_CXXFLAGS) -MMD -MP -c -o \$\@ \$\<) -build/S_source.d: ; +$ENV{TRICK_BUILD_DIR}build/S_source.d: ; --include build/S_source.d +-include $ENV{TRICK_BUILD_DIR}build/S_source.d # MODEL_OBJECTS ================================================================ # This function allows users to specify target-specific variables for individual # or groups of source files. For example: # \$(call FIND_MODEL_OBJECTS, /path/to/file /path/to/directory \$(LIST_OF_PATHS)): TRICK_CXXFLAGS += -Werror -FIND_MODEL_OBJECTS = \$(foreach PATH, \$1, \$(filter \$(addprefix build, \$(addsuffix %, \$(PATH))), \$(MODEL_OBJECTS))) +FIND_MODEL_OBJECTS = \$(foreach PATH, \$1, \$(filter \$(addprefix $ENV{TRICK_BUILD_DIR}build, \$(addsuffix %, \$(PATH))), \$(MODEL_OBJECTS))) -" ; +"; # List out all of the object files and put the list in a file that we can pass to the linker. # Passing all of them directly to the linker in the command line can exceed the line limit. -open MODEL_LINK_LIST, ">build/model_link_list" or die "Could not open build/model_link_list" ; +open MODEL_LINK_LIST, ">$ENV{TRICK_BUILD_DIR}build/model_link_list" + or die "Could not open $ENV{TRICK_BUILD_DIR}build/model_link_list"; -my %files_by_extension ; +my %files_by_extension; foreach my $directory ( keys %files_by_dir ) { - foreach my $extension ( grep { /^\.(c|cc|C|cxx|cpp|c\+\+)$/ } keys %{$files_by_dir{$directory}} ) { - foreach my $file ( @{$files_by_dir{$directory}{$extension}} ) { - push @{$files_by_extension{$extension}} , "build$directory$file.o" ; + foreach my $extension ( grep { /^\.(c|cc|C|cxx|cpp|c\+\+)$/ } keys %{ $files_by_dir{$directory} } ) { + foreach my $file ( @{ $files_by_dir{$directory}{$extension} } ) { + push @{ $files_by_extension{$extension} }, "$ENV{TRICK_BUILD_DIR}build${directory}${file}.o"; } } } foreach my $extension ( keys %files_by_extension ) { - print MAKEFILE "MODEL_OBJECTS${extension} :=" ; - foreach my $file ( @{$files_by_extension{$extension}} ) { - print MAKEFILE " \\\n $file" ; - print MODEL_LINK_LIST "$file\n" ; + print MAKEFILE "MODEL_OBJECTS${extension} :="; + foreach my $file ( @{ $files_by_extension{$extension} } ) { + print MAKEFILE " \\\n $file"; + print MODEL_LINK_LIST "$file\n"; } - print MAKEFILE "\n\n" + print MAKEFILE "\n\n"; } -close MODEL_LINK_LIST ; +close MODEL_LINK_LIST; -print MAKEFILE "MODEL_OBJECTS :=" ; +print MAKEFILE "MODEL_OBJECTS :="; foreach my $extension ( keys %files_by_extension ) { - print MAKEFILE " \${MODEL_OBJECTS$extension}" ; + print MAKEFILE " \${MODEL_OBJECTS$extension}"; } # Write out the compile rules for each type of file. @@ -263,17 +278,18 @@ print MAKEFILE " # See https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html # and https://www.gnu.org/software/make/manual/html_node/Secondary-Expansion.html -.SECONDEXPANSION:" ; +.SECONDEXPANSION:"; foreach my $extension ( keys %files_by_extension ) { - my $compiler = "TRICK_" . ($extension eq ".c" ? "CC" : "CXX") ; - my $flags = $extension eq ".c" ? "C" : "CXX" ; - my $command = "\$($compiler) \$(TRICK_${flags}FLAGS) \$(TRICK_SYSTEM_${flags}FLAGS) -I\$(build/Makefile_overrides" or die "Could not open build/Makefile_overrides" ; +open MAKEFILEOVER, ">$ENV{TRICK_BUILD_DIR}build/Makefile_overrides" + or die "Could not open $ENV{TRICK_BUILD_DIR}build/Makefile_overrides"; foreach $k ( sort keys %files_by_dir ) { + # Look for makefile_overrides in the current directory. # If no such file exists AND this directory is named "src", look for it one level up. # Silly, but baggage we're stuck with. - my $makefile_overrides = "${k}makefile_overrides" ; - if (not -e $makefile_overrides and $k =~ /\/src\/$/) { - $makefile_overrides = dirname($k) . "/makefile_overrides" ; + my $makefile_overrides = "${k}makefile_overrides"; + if ( not -e $makefile_overrides and $k =~ /\/src\/$/ ) { + $makefile_overrides = dirname($k) . "/makefile_overrides"; } - if (open OV_FILE, $makefile_overrides) { - while ( ) { - s/(#.*)// ; - my ($comment) = $1 ; - s/\$[{(]CURDIR[})]\/(\S+)/$k\/$1/g ; - s/(?:\$[{(]CURDIR[})]\/)?(\S*)\$[{(]OBJ_DIR[})]/$k\/$1object_\${TRICK_HOST_CPU}/g ; - s/\$[{(]CURDIR[})]/$k/g ; - while ( s,/[^/.]+/\.\.,, ) {} - s//$comment/ ; - if ( s/^objects\s*:\s*// ) { + if ( open OV_FILE, $makefile_overrides ) { + while () { + s/(#.*)//; + my ($comment) = $1; + s/\$[{(]CURDIR[})]\/(\S+)/$k\/$1/g; + s/(?:\$[{(]CURDIR[})]\/)?(\S*)\$[{(]OBJ_DIR[})]/$k\/$1object_\${TRICK_HOST_CPU}/g; + s/\$[{(]CURDIR[})]/$k/g; + while (s,/[^/.]+/\.\.,,) { } + s//$comment/; + if (s/^objects\s*:\s*//) { foreach my $extension ( keys %files_by_extension ) { - foreach my $file (@{$files_by_dir{$k}{$extension}}) { - $files_by_dir{$k}{overrides} .= "build$k${file}.o \\\n" ; + foreach my $file ( @{ $files_by_dir{$k}{$extension} } ) { + $files_by_dir{$k}{overrides} .= "$ENV{TRICK_BUILD_DIR}build/${k}${file}.o \\\n"; } } - $files_by_dir{$k}{overrides} .= ": $_" + $files_by_dir{$k}{overrides} .= ": $_"; } - elsif ( s/(.+)_objects\s*:\s*// ) { - if (scalar @{$files_by_dir{$k}{".$1"}}) { - foreach my $file (@{$files_by_dir{$k}{".$1"}}) { - $files_by_dir{$k}{overrides} .= "build$k$file.o \\\n" ; + elsif (s/(.+)_objects\s*:\s*//) { + if ( scalar @{ $files_by_dir{$k}{".$1"} } ) { + foreach my $file ( @{ $files_by_dir{$k}{".$1"} } ) { + $files_by_dir{$k}{overrides} .= "$ENV{TRICK_BUILD_DIR}build/${k}${file}.o \\\n"; } - $files_by_dir{$k}{overrides} .= ": $_" + $files_by_dir{$k}{overrides} .= ": $_"; } } else { - $files_by_dir{$k}{overrides} .= $_ ; + $files_by_dir{$k}{overrides} .= $_; } } - close OV_FILE ; - print MAKEFILEOVER "# Overrides from $makefile_overrides\n" ; - print MAKEFILEOVER "MAKEFILE_LIST += $makefile_overrides\n\n" ; - print MAKEFILEOVER "$files_by_dir{$k}{overrides}\n" ; - print MAKEFILEOVER "MAKEFILE_LIST := \$(filter-out $makefile_overrides,\$(MAKEFILE_LIST))\n\n" ; + close OV_FILE; + print MAKEFILEOVER "# Overrides from $makefile_overrides\n"; + print MAKEFILEOVER "MAKEFILE_LIST += $makefile_overrides\n\n"; + print MAKEFILEOVER "$files_by_dir{$k}{overrides}\n"; + print MAKEFILEOVER "MAKEFILE_LIST := \$(filter-out $makefile_overrides,\$(MAKEFILE_LIST))\n\n"; } } -close MAKEFILEOVER ; +close MAKEFILEOVER; + +if ( $ENV{'AM_I_TRICKIFYING'} ) { + + # %non_lib_processed_files consists of the #include tree starting from S_source.hh, plus listed lib dependencies. + # not included are the #include trees of library dependencies. + my %trickify_deps = %non_lib_processed_files; -open TRICKIFYDEPS, ">build/trickify_deps" or die "Could not open build/trickify_deps" ; -print TRICKIFYDEPS map {"$_\n"} (sort keys %non_lib_processed_files) ; +# to ensure trickify deps include ALL files needed to build the sim, we must grab the headers missing from %non_lib_processed_files +# get_s_source_deps() is the function used by make_makefile_swig to grabe its dep list. +# this function traverses the #includes of lib dependencies, so it will fill in the gaps in our list. + ( my $files_to_process ) = get_s_source_deps(); + foreach my $ftp (@$files_to_process) { + $trickify_deps{$ftp} = 1; + } + + open TRICKIFYDEPS, ">$ENV{TRICK_BUILD_DIR}build/trickify_deps" + or die "Could not open $ENV{TRICK_BUILD_DIR}build/trickify_deps"; + print TRICKIFYDEPS map { "$_\n" } ( sort keys %trickify_deps ); + close TRICKIFYDEPS; +} # write out all of files we processed as dependencies to Makefile_src -open MAKEFILEDEPS, ">build/Makefile_src_deps" or die "Could not open build/Makefile_src_deps" ; -print MAKEFILEDEPS "build/Makefile_src:" ; -print MAKEFILEDEPS map {"\\\n $_"} (sort keys %non_lib_processed_files) ; -print MAKEFILEDEPS "\n\n" ; -print MAKEFILEDEPS map {"$_:\n"} (sort keys %non_lib_processed_files) ; -close MAKEFILEDEPS ; +open MAKEFILEDEPS, ">$ENV{TRICK_BUILD_DIR}build/Makefile_src_deps" + or die "Could not open $ENV{TRICK_BUILD_DIR}build/Makefile_src_deps"; +print MAKEFILEDEPS "$ENV{TRICK_BUILD_DIR}build/Makefile_src:"; +print MAKEFILEDEPS map { "\\\n $_" } ( sort keys %non_lib_processed_files ); +print MAKEFILEDEPS "\n\n"; +print MAKEFILEDEPS map { "$_:\n" } ( sort keys %non_lib_processed_files ); +close MAKEFILEDEPS; # write out all of the files we used to S_library_list -open LIB_LIST, ">build/S_library_list" or die "Could not open build/S_library_list" ; -print LIB_LIST map {"$_\n"} (sort keys %processed_files) ; -close LIB_LIST ; +open LIB_LIST, ">$ENV{TRICK_BUILD_DIR}build/S_library_list" + or die "Could not open $ENV{TRICK_BUILD_DIR}build/S_library_list"; +print LIB_LIST map { "$_\n" } ( sort keys %processed_files ); +close LIB_LIST; -if($ENV{'AM_I_TRICKIFYING'}) -{ - 0 or die; +if ( $ENV{'AM_I_TRICKIFYING'} ) { + 0 or exit 1; } diff --git a/libexec/trick/make_makefile_swig b/libexec/trick/make_makefile_swig index fc8df4d43..f0247b7be 100755 --- a/libexec/trick/make_makefile_swig +++ b/libexec/trick/make_makefile_swig @@ -3,393 +3,12 @@ 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 verbose_build; -use get_paths; -use strict; - -my @exclude_paths; -my @swig_exclude_paths; -my @ext_lib_paths; -my @ext_lib_paths_overrides; -my @files_to_process; -my @ext_lib_files; -my %md5s; -my $verbose_build = verbose_build(); -my %trick_headers; -my %python_modules; -my %python_module_dirs; - -sub read_files_to_process() { - ( my $version, my $thread ) = get_trick_version(); - ( my $year ) = $version =~ /^(\d+)/; - ( my $cc = gte("TRICK_CC") ) =~ s/\n//; - - # Prepend -I to each include path before we pass them to the compiler - my @include_paths = map( "-I$_", - ( - get_include_paths(), "$ENV{TRICK_HOME}", - "$ENV{TRICK_HOME}/include", "$ENV{TRICK_HOME}/include/trick/compat", - "$ENV{TRICK_HOME}/trick_source", "../include" - ) ); - my @defines = ( get_defines(), "-DTRICK_VER=$year", "-DSWIG" ); - - # get the list of header files from the compiler - open FILE_LIST, "$cc -MM @include_paths @defines S_source.hh |"; - my $dir = dirname( abs_path("S_source.hh") ); - my %files; - my %ext_libs; - while () { - 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} ) ); - $md5s{$word} = md5_hex($word); - - # skip system headers that are missed by the compiler -MM flag - next if ( $word =~ /^\/usr\/include/ ); - next if ( $word =~ /^\/usr\/local\/include/ ); - - # skip Trick headers - my $trick_home = abs_path( $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(.*)/ or abs_path($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(.*)/ or abs_path($word) =~ /^\Q$path\E(.*)/ ) { - print "SWIG Skip TRICK_SWIG_EXCLUDE: $path$1\n" if $verbose_build; - next outer; - } - } - - # separate paths in TRICK_EXT_LIB_DIRS - foreach my $path (@ext_lib_paths) { - if ( $word =~ /^\Q$path\E(.*)/ or abs_path($word) =~ /^\Q$path\E(.*)/ ) { - if ( get_containing_path( $word, @ext_lib_paths_overrides ) eq 0 ) { - 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 die "Could not open build/Makefile_swig_deps for writing"; - print DEPENDENCIES_FILE "build/Makefile_swig:"; - foreach my $file ( @files_to_process, @ext_lib_files ) { - print DEPENDENCIES_FILE " \\\n " . $file; - } - close DEPENDENCIES_FILE; -} - -sub get_trick_headers() { - foreach my $f ( @files_to_process, @ext_lib_files ) { - my %trick_header = extract_trick_header( $f, do { local ( @ARGV, $/ ) = $f; <> }, 0, 0 ); - if ( exists $trick_header{python_module} ) { - $trick_headers{$f}{python_module} = $trick_header{python_module}; - ( $trick_headers{$f}{python_module_dir} = $trick_header{python_module} ) =~ s/\./\//g; - $python_modules{ $trick_headers{$f}{python_module} } = 1; - $python_module_dirs{ $trick_headers{$f}{python_module_dir} } = 1; - } - $trick_headers{$f}{swig} = $trick_header{swig} if ( exists $trick_header{swig} ); - } -} - -sub has_swig_no { - my $result = $trick_headers{ $_[0] }{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 $s_source_md5 = md5_hex( abs_path("S_source.hh") ); - my $swig_sim_dir = ".trick"; - my $swig_sim_zip = "trick.zip"; - my $swig_src_dir = "build"; - - open MAKEFILE, ">build/Makefile_swig" or die "Could not open build/Makefile_swig for writing"; - open PY_LINK_LIST, ">build/py_link_list" or die "Could not open build/py_link_list for writing"; - open TRICKIFY_PY_LINK_LIST, ">build/trickify_py_link_list" - or die "Could not open build/trickify_py_link_list for writing"; - print PY_LINK_LIST "build/init_swig_modules.o\n"; - print PY_LINK_LIST "build/top.o\n"; - - print MAKEFILE - "TRICK_SYSTEM_SWIG_CFLAGS := -I../include \${PYTHON_INCLUDES} -Wno-shadow -Wno-missing-field-initializers - -ifeq (\$(IS_CC_CLANG), 1) - TRICK_SYSTEM_SWIG_CFLAGS += -Wno-self-assign -Wno-sometimes-uninitialized -Wno-deprecated-register -Wno-unused-variable -Wno-unused-but-set-variable -Wno-cast-function-type-mismatch -else - TRICK_SYSTEM_SWIG_CFLAGS += -Wno-unused-but-set-variable -Wno-maybe-uninitialized - ifeq (\$(shell test \$(GCC_MAJOR) -ge 8; echo \$\$?), 0) - TRICK_SYSTEM_SWIG_CFLAGS += -Wno-cast-function-type - endif -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\$(call ECHO_AND_LOG,/bin/cp -f \$< \$@) - -# SWIG_I ======================================================================= - -SWIG_I ="; - - foreach my $file (@files_to_process) { - ( my $swig_file = $file ) =~ s/(\.[^.]*)?$/_py/; - print MAKEFILE " \\\n build$swig_file.i"; - print PY_LINK_LIST "build$swig_file.o\n"; - if ( !( $swig_file =~ /(.*)S_source_py$/ ) ) { - print TRICKIFY_PY_LINK_LIST "build$swig_file.o\n"; - } - } - - print MAKEFILE " - -define create_convert_swig_rule -build/%_py.i: /%.\$1 -\t\$\$(call ECHO_AND_LOG,\${TRICK_HOME}/\$(LIBEXEC)/trick/convert_swig \$\${TRICK_CONVERT_SWIG_FLAGS} \$\$<) -endef - -\$(foreach EXTENSION,H h hh hxx h++ hpp,\$(eval \$(call create_convert_swig_rule,\$(EXTENSION)))) - -build/top.i: build/CP_instances -\t\$(call ECHO_AND_LOG,\${PYTHON} \${TRICK_HOME}/\${LIBEXEC}/trick/create_top_dot_i) - -# SWIG_SRC ===================================================================== - -SWIG_SRC = \$(patsubst %.i,%.cpp,\$(SWIG_I)) $swig_src_dir/top.cpp - -\$(SWIG_SRC) : %.cpp: %.i | %.d \$(SWIG_I) -\t\$(PRINT_SWIG) -\t\$(call ECHO_AND_LOG,\$(SWIG) \$(TRICK_INCLUDE) \$(TRICK_DEFINES) \$(TRICK_VERSIONS) \$(TRICK_SWIG_FLAGS) -c++ -python -includeall -ignoremissing -w201 -w303 -w315 -w325 -w362 -w389 -w401 -w451 -MMD -MP -outdir $swig_sim_dir -o \$@ \$<) +use swig_make; -\$(SWIG_SRC:.cpp=.d): ; - --include \$(SWIG_SRC:.cpp=.d) - -# SWIG_OBJECTS ================================================================= - -SWIG_OBJECTS = \$(patsubst %.cpp,%.o,\$(SWIG_SRC)) $swig_src_dir/init_swig_modules.o - -\$(SWIG_OBJECTS): %.o: %.cpp -\t\$(PRINT_COMPILE_SWIG) -\t\$(call ECHO_AND_LOG,\$(TRICK_CXX) \$(TRICK_CXXFLAGS) \$(TRICK_SYSTEM_CXXFLAGS) \$(TRICK_SWIG_CFLAGS) \$(TRICK_SYSTEM_SWIG_CFLAGS) -Wno-unused-parameter -c -o \$@ \$<) - -\$(S_MAIN): \$(SWIG_OBJECTS) - -LINK_LISTS += \$(LD_FILELIST)build/py_link_list - -# $swig_sim_zip =================================================================== - -$swig_sim_zip: \$(SWIG_SRC) \$(TRICK_FIXED_PYTHON) $swig_sim_dir/__init__.py -\t\$(info \$(call COLOR,Compiling) Python modules) -\t\$(call ECHO_AND_LOG,\$(PYTHON) -m compileall -q $swig_sim_dir) -\t\$(info \$(call COLOR,Zipping) Python modules into \$@) -\t\$(call ECHO_AND_LOG,ln -sf $swig_sim_dir trick) -\t\$(call ECHO_AND_LOG,zip -rq $swig_sim_zip trick) -\t\$(call ECHO_AND_LOG,rm -f trick) - - -all: $swig_sim_zip -"; - - close MAKEFILE; - close PY_LINK_LIST; - close TRICKIFY_PY_LINK_LIST; - - open SWIGLIB, ">build/S_library_swig" or die "Could not open build/S_library_swig for writing"; - foreach my $file (@files_to_process) { - print SWIGLIB "$file\n"; - } - close SWIGLIB; - - open INITSWIGFILE, ">build/init_swig_modules.cpp" or die "Could not open build/init_swig_modules.cpp for writing"; - print INITSWIGFILE "#include \n"; - print INITSWIGFILE "#if PY_VERSION_HEX >= 0x03000000\n"; - print INITSWIGFILE "extern \"C\" {\n\n"; - - foreach my $file ( @files_to_process, @ext_lib_files ) { - print INITSWIGFILE "PyObject * PyInit__m$md5s{$file}(void) ; /* $file */\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 my $file ( @files_to_process, @ext_lib_files ) { - next if ( $file =~ /S_source.hh/ ); - print INITSWIGFILE " PyImport_AppendInittab(\"_m$md5s{$file}\", PyInit__m$md5s{$file}) ;\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 my $file ( @files_to_process, @ext_lib_files ) { - print INITSWIGFILE "void init_m$md5s{$file}(void) ; /* $file */\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 my $file ( @files_to_process, @ext_lib_files ) { - next if ( $file =~ /S_source.hh/ ); - print INITSWIGFILE " init_m$md5s{$file}() ;\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 $swig_sim_dir ) { - mkdir $swig_sim_dir; - } - open INITFILE, ">$swig_sim_dir/__init__.py" or die "Could not open $swig_sim_dir/__init__.py for writing"; - - 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() + \"/$swig_sim_zip/trick\")\n"; - foreach my $dir ( keys %python_module_dirs ) { - print INITFILE "sys.path.append(os.getcwd() + \"/$swig_sim_zip/trick/$dir\")\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 my $file ( @files_to_process, @ext_lib_files ) { - print INITFILE "# $file\n"; - print INITFILE "import _m$md5s{$file}\n"; - print INITFILE "combine_cvars(all_cvars, cvar)\n"; - print INITFILE "cvar = None\n\n"; - } - - foreach my $file ( @files_to_process, @ext_lib_files ) { - print INITFILE "# $file\n"; - print INITFILE "from m$md5s{$file} import *\n"; - } - - foreach my $mod ( keys %python_modules ) { - print INITFILE "import trick.$mod\n"; - } - - print INITFILE "\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 my $dir ( keys %python_module_dirs ) { - system("mkdir -p $swig_sim_dir/$dir"); - open MODULE_INITFILE, ">$swig_sim_dir/$dir/__init__.py"; - foreach my $file ( @files_to_process, @ext_lib_files ) { - if ( exists $trick_headers{$file}{python_module_dir} and $trick_headers{$file}{python_module_dir} eq $dir ) - { - print MODULE_INITFILE "# $file\n"; - print MODULE_INITFILE "import _m$md5s{$file}\n"; - print MODULE_INITFILE "from m$md5s{$file} import *\n"; - } - } - close MODULE_INITFILE; - } - - return; -} +use strict; -@exclude_paths = get_paths("TRICK_EXCLUDE"); -@swig_exclude_paths = get_paths("TRICK_SWIG_EXCLUDE"); -@ext_lib_paths = get_paths("TRICK_EXT_LIB_DIRS"); -@ext_lib_paths_overrides = get_paths("TRICK_EXT_LIB_DIRS_OVERRIDES"); read_files_to_process(); + write_makefile_swig_deps(); get_trick_headers(); @@ -397,4 +16,7 @@ get_trick_headers(); # 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(); + +write_lib_files(); diff --git a/libexec/trick/pm/get_hashtag_includes.pm b/libexec/trick/pm/get_hashtag_includes.pm new file mode 100644 index 000000000..4b7d1314c --- /dev/null +++ b/libexec/trick/pm/get_hashtag_includes.pm @@ -0,0 +1,35 @@ +package get_hashtag_includes; + +use FindBin qw($RealBin); +use lib "$RealBin/"; + +use File::Basename; +use Cwd; +use Cwd 'abs_path'; +use trick_print; + +@ISA = qw(Exporter); +@EXPORT = qw(get_hashtag_includes); + +use strict; + +sub get_hashtag_includes($) { + my ($file_list) = @_; + my %includes; + + foreach my $file (@$file_list) { + open FILE, "$file" or die "Failed to open $file\n"; + while () { + chomp; + if ( $_ =~ /^#\s*include\s*\"(.*)\"$/ || $_ =~ /^#\s*include\s*\<(.*)\>$/ ) { + if ( defined($1) ) { + chomp $1; + $includes{$1} = 1; + } + } + } + } + return \%includes; +} + +1; diff --git a/libexec/trick/pm/get_lib_deps.pm b/libexec/trick/pm/get_lib_deps.pm index 8876d1759..63c3f70cf 100644 --- a/libexec/trick/pm/get_lib_deps.pm +++ b/libexec/trick/pm/get_lib_deps.pm @@ -1,162 +1,179 @@ -package get_lib_deps ; +package get_lib_deps; -use File::Basename ; +use File::Basename; use Cwd 'abs_path'; -use File::Path qw(make_path) ; -use Exporter (); -use gte ; -use get_paths ; -use verbose_build ; -@ISA = qw(Exporter); -@EXPORT = qw(get_lib_deps write_lib_deps); +use File::Path qw(make_path); +use Exporter (); +use gte; +use get_paths; +use verbose_build; +use trick_version; +use Digest::MD5 qw(md5_hex); +@ISA = qw(Exporter); +@EXPORT = qw(get_lib_deps write_lib_deps get_s_source_deps); -use strict ; +use strict; -my $verbose_build = verbose_build() ; -my @ext_lib_paths = get_paths( "TRICK_EXT_LIB_DIRS" ) ; -my @ext_lib_paths_overrides = get_paths( "TRICK_EXT_LIB_DIRS_OVERRIDES" ) ; +my $verbose_build = verbose_build(); +my @ext_lib_paths = get_paths("TRICK_EXT_LIB_DIRS"); +my @ext_lib_paths_overrides = get_paths("TRICK_EXT_LIB_DIRS_OVERRIDES"); sub get_lib_deps ($$) { - my ($contents, $source_file_name) = @_ ; - my ($lib_deps) ; - my (@lib_list) ; - my (@inc_paths) ; - my (@raw_lib_deps) ; + my ( $contents, $source_file_name ) = @_; + my ($lib_deps); + my (@lib_list); + my (@inc_paths); + my (@raw_lib_deps); # Doxygen style - @lib_list = ($contents =~ /(?:@|\\)trick_li(?:nk|b)_dependency\s*{\s*(.*?)\s*}/gs) ; + @lib_list = ( $contents =~ /(?:@|\\)trick_li(?:nk|b)_dependency\s*{\s*(.*?)\s*}/gs ); # Classic style # library dependency regular expression will match all the way through last parenthesis followed by # another field in the trick header, a doxygen style keyword, or the end of comment *. # we capture all library dependencies at once into raw_lib_deps - @raw_lib_deps = ($contents =~ /LIBRARY[ _]DEPENDENC(?:Y|IES)\s*:(.*?)(?=^[ \t]*\**[ \t]*[A-Z][A-Z _\t]*:|\*\/)/gmsi) ; - foreach my $r ( @raw_lib_deps ) { + @raw_lib_deps = + ( $contents =~ /LIBRARY[ _]DEPENDENC(?:Y|IES)\s*:(.*?)(?=^[ \t]*\**[ \t]*[A-Z][A-Z _\t]*:|\*\/)/gmsi ); + foreach my $r (@raw_lib_deps) { + # if there is preprocessor directive in the library dependencies, run the text through cpp. if ( $r =~ /#/ ) { - (my $cc = gte("TRICK_CC")) =~ s/\n// ; - my @defines = get_defines() ; - my $temp ; - open FILE, "echo \"$r\" | cpp -P @defines |" ; - while ( ) { - $temp .= $_ ; + ( my $cc = gte("TRICK_CC") ) =~ s/\n//; + my @defines = get_defines(); + my $temp; + open FILE, "echo \"$r\" | cpp -P @defines |"; + while () { + $temp .= $_; } - $r = $temp ; + $r = $temp; } + # Strip leading comment markers from continuation lines before extracting '(...)' items. - $r =~ s/^\s*\**\s*//mg ; - push @lib_list , ($r =~ /\(([^()]+)\)/g) ; + $r =~ s/^\s*\**\s*//mg; + push @lib_list, ( $r =~ /\(([^()]+)\)/g ); } - @inc_paths = get_include_paths() ; + @inc_paths = get_include_paths(); + # Get only the include paths that exist - my @valid_inc_paths ; + my @valid_inc_paths; foreach (@inc_paths) { - push @valid_inc_paths , $_ if ( -e $_ ) ; + push @valid_inc_paths, $_ if ( -e $_ ); } - @inc_paths = @valid_inc_paths ; + @inc_paths = @valid_inc_paths; - my ($file_path_dir) = dirname($source_file_name) ; - $file_path_dir =~ s/\/+$// ; # remove trailing slash - $file_path_dir =~ s/\/include$// ; + my ($file_path_dir) = dirname($source_file_name); + $file_path_dir =~ s/\/+$//; # remove trailing slash + $file_path_dir =~ s/\/include$//; - my %resolved_files ; - my @ordered_resolved_files ; + my %resolved_files; + my @ordered_resolved_files; foreach my $l (@lib_list) { - my $found = 0 ; - $l =~ s/\(|\)|\s+//g ; - $l =~ s/\$\{(.+?)\}/$ENV{$1}/eg ; - next if ( $l eq "" ) ; + my $found = 0; + $l =~ s/\(|\)|\s+//g; + $l =~ s/\$\{(.+?)\}/$ENV{$1}/eg; + next if ( $l eq "" ); if ( $l =~ /\.a$/ ) { - my ($rel_dir) = dirname($l) ; - foreach my $inc ( dirname($source_file_name) , @inc_paths) { + my ($rel_dir) = dirname($l); + foreach my $inc ( dirname($source_file_name), @inc_paths ) { if ( -e "$inc/$rel_dir" ) { - my $f = abs_path("$inc/$rel_dir") . "/" . basename($l) ; - if ( ! exists $resolved_files{$f} ) { - $resolved_files{$f} = 1 ; - push @ordered_resolved_files , $f ; + my $f = abs_path("$inc/$rel_dir") . "/" . basename($l); + if ( !exists $resolved_files{$f} ) { + $resolved_files{$f} = 1; + push @ordered_resolved_files, $f; } - $found = 1 ; - last ; + $found = 1; + last; } } - } elsif ( $l !~ /\.o$/ ) { - foreach my $inc ( dirname($source_file_name) , @inc_paths) { + } + elsif ( $l !~ /\.o$/ ) { + foreach my $inc ( dirname($source_file_name), @inc_paths ) { if ( -e "$inc/$l" ) { + #print "found $inc/$l$ext\n" ; - my $f = abs_path(dirname("$inc/$l")) . "/" . basename("$inc/$l") ; - if ( ! exists $resolved_files{$f} ) { - $resolved_files{$f} = 1 ; - push @ordered_resolved_files , $f ; + my $f = abs_path( dirname("$inc/$l") ) . "/" . basename("$inc/$l"); + if ( !exists $resolved_files{$f} ) { + $resolved_files{$f} = 1; + push @ordered_resolved_files, $f; } - $found = 1 ; - last ; + $found = 1; + last; } } - } else { - $l =~ s/o$// ; - my ($rel_dir) = dirname($l) ; - my ($base) = basename($l) ; + } + else { + $l =~ s/o$//; + my ($rel_dir) = dirname($l); + my ($base) = basename($l); if ( $rel_dir =~ /^\// ) { + # if the directory name of the dependency is absolute - foreach my $ext ( "cpp" , "cc" , "c" , "c++" , "cxx" , "C" ) { + foreach my $ext ( "cpp", "cc", "c", "c++", "cxx", "C" ) { if ( -e "$rel_dir/$base$ext" ) { - my $f = abs_path("$rel_dir") . "/$base$ext" ; + my $f = abs_path("$rel_dir") . "/$base$ext"; + #print "found $f\n" ; - if ( ! exists $resolved_files{$f} ) { - $resolved_files{$f} = 1 ; - push @ordered_resolved_files , $f ; + if ( !exists $resolved_files{$f} ) { + $resolved_files{$f} = 1; + push @ordered_resolved_files, $f; } - $found = 1 ; + $found = 1; } elsif ( -e "$rel_dir/src/$base$ext" ) { - my $f = abs_path("$rel_dir/src") . "/$base$ext" ; + my $f = abs_path("$rel_dir/src") . "/$base$ext"; + #print "found $f\n" ; - if ( ! exists $resolved_files{$f} ) { - $resolved_files{$f} = 1 ; - push @ordered_resolved_files , $f ; + if ( !exists $resolved_files{$f} ) { + $resolved_files{$f} = 1; + push @ordered_resolved_files, $f; } - $found = 1 ; + $found = 1; } } - } else { + } + else { # if the directory name of the dependency is a relative directory - foreach my $inc ( $file_path_dir , @inc_paths) { - foreach my $ext ( "cpp" , "cc" , "c" , "c++" , "cxx" , "C" ) { + foreach my $inc ( $file_path_dir, @inc_paths ) { + foreach my $ext ( "cpp", "cc", "c", "c++", "cxx", "C" ) { if ( -e "$inc/$rel_dir/$base$ext" ) { - my $f = abs_path("$inc/$rel_dir") . "/$base$ext" ; + my $f = abs_path("$inc/$rel_dir") . "/$base$ext"; + #print "found $f\n" ; - if ( ! exists $resolved_files{$f} ) { - $resolved_files{$f} = 1 ; - push @ordered_resolved_files , $f ; + if ( !exists $resolved_files{$f} ) { + $resolved_files{$f} = 1; + push @ordered_resolved_files, $f; } - $found = 1 ; - last ; + $found = 1; + last; } elsif ( -e "$inc/$rel_dir/src/$base$ext" ) { - my $f = abs_path("$inc/$rel_dir/src") . "/$base$ext" ; + my $f = abs_path("$inc/$rel_dir/src") . "/$base$ext"; + #print "found $f\n" ; - if ( ! exists $resolved_files{$f} ) { - $resolved_files{$f} = 1 ; - push @ordered_resolved_files , $f ; + if ( !exists $resolved_files{$f} ) { + $resolved_files{$f} = 1; + push @ordered_resolved_files, $f; } - $found = 1 ; - last ; + $found = 1; + last; } } - last if ( $found == 1 ) ; + last if ( $found == 1 ); } } + # file not found, append the "o" we stripped for the error message - $l .= "o" ; + $l .= "o"; } if ( $found == 0 ) { - print STDERR "Warning $source_file_name\n " ; + print STDERR "Warning $source_file_name\n "; if ( $l =~ /^(sim_services)/ or $l =~ /^(er7_utils)/ ) { - print STDERR "It is not necessary to list dependencies found in $1: \"$l\"\n" ; - } else { - print STDERR "Could not find dependency \"$l\"\n" ; + print STDERR "It is not necessary to list dependencies found in $1: \"$l\"\n"; + } + else { + print STDERR "Could not find dependency \"$l\"\n"; } } } @@ -165,67 +182,161 @@ sub get_lib_deps ($$) { foreach (@ordered_resolved_files) { if ( my $exclude_path = get_containing_path( $_, @ext_lib_paths ) ) { if ( get_containing_path( $_, @ext_lib_paths_overrides ) eq 0 ) { - print "Dep Skip TRICK_EXT_LIB_DIRS: $exclude_path" . substr($_, length $exclude_path) . "\n" if $verbose_build ; - next ; + print "Dep Skip TRICK_EXT_LIB_DIRS: $exclude_path" + . substr( $_, length $exclude_path ) . "\n" + if $verbose_build; + next; } } - push @included_ordered_resolved_files, $_ ; + push @included_ordered_resolved_files, $_; } - return @included_ordered_resolved_files ; + return @included_ordered_resolved_files; } sub write_lib_deps($) { - my $deps_changed ; - my ($source_file_name) = @_ ; - my $contents ; + my $deps_changed; + my ($source_file_name) = @_; + my $contents; { # read source file in slurp mode. Keep the scope of undefining $/ (slurp) to this read - local $/ = undef ; - open SOURCE, $source_file_name or warn "cannot read $source_file_name: $!" ; - $contents = ; - close SOURCE ; + local $/ = undef; + open SOURCE, $source_file_name or warn "cannot read $source_file_name: $!"; + $contents = ; + close SOURCE; } + # Get the library dependencies - my (@resolved_files) = get_lib_deps($contents, $source_file_name) ; + my (@resolved_files) = get_lib_deps( $contents, $source_file_name ); + # Remove a self dependency if it exists - @resolved_files = grep { $_ ne $source_file_name } @resolved_files ; + @resolved_files = grep { $_ ne $source_file_name } @resolved_files; # Build the library dependencies file name to store results - my ( $file, $dir, $suffix) = fileparse($source_file_name, qr/\.[^.]*/) ; - my ($lib_dep_file_name) = "build$dir${file}${suffix}.lib_deps" ; - if ( ! -e "build$dir" ) { - make_path("build$dir") ; + my ( $file, $dir, $suffix ) = fileparse( $source_file_name, qr/\.[^.]*/ ); + my ($lib_dep_file_name) = "$ENV{TRICK_BUILD_DIR}build$dir${file}${suffix}.lib_deps"; + if ( !-e "build$dir" ) { + make_path("$ENV{TRICK_BUILD_DIR}build$dir"); } if ( -e $lib_dep_file_name ) { + # If the library dependency file exists open the old lib dep file # and compare the new and old lists. - open OLDLIBDEP, "$lib_dep_file_name" ; - my @old_resolved = ; - close OLDLIBDEP ; - chomp @old_resolved ; + open OLDLIBDEP, "$lib_dep_file_name"; + my @old_resolved = ; + close OLDLIBDEP; + chomp @old_resolved; + + if ( join( ", ", @old_resolved ) eq join( ", ", @resolved_files ) ) { - if (join(", ", @old_resolved) eq join(", ", @resolved_files)) { #print "Library dependencies unchanged for $source_file_name\n" ; - $deps_changed = 0 ; - } else { + $deps_changed = 0; + } + else { #print "Library dependencies changed for $source_file_name\n" ; - $deps_changed = 1 ; + $deps_changed = 1; } - } else { + } + else { # If the library dependency does not exist, the deps changed. - $deps_changed = 1 ; + $deps_changed = 1; } # if the library dependencies changed, write out the new dependency list - if ( $deps_changed ) { - open LIBDEP, ">$lib_dep_file_name" ; - print LIBDEP map {"$_\n"} @resolved_files ; - close LIBDEP ; + if ($deps_changed) { + open LIBDEP, ">$lib_dep_file_name"; + print LIBDEP map { "$_\n" } @resolved_files; + close LIBDEP; } # return the deps changed flag and the list of dependencies - return $deps_changed , @resolved_files ; + return $deps_changed, @resolved_files; +} + +sub get_s_source_deps() { + ( my $version, my $thread ) = get_trick_version(); + ( my $year ) = $version =~ /^(\d+)/; + ( my $cc = gte("TRICK_CC") ) =~ s/\n//; + + # Prepend -I to each include path before we pass them to the compiler + my @include_paths = map( "-I$_", + ( + get_include_paths(), "$ENV{TRICK_HOME}", + "$ENV{TRICK_HOME}/include", "$ENV{TRICK_HOME}/include/trick/compat", + "$ENV{TRICK_HOME}/trick_source", "../include" + ) ); + my @defines = ( get_defines(), "-DTRICK_VER=$year", "-DSWIG" ); + + my @exclude_paths = get_paths("TRICK_EXCLUDE"); + my @swig_exclude_paths = get_paths("TRICK_SWIG_EXCLUDE"); + my %local_md5s; + + # get the list of header files from the compiler + open FILE_LIST, "$cc -MM @include_paths @defines $ENV{'TRICK_BUILD_DIR'}S_source.hh |"; + my $dir = dirname( abs_path("S_define") ); + my %files; + my %ext_libs; + while () { + 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( $local_md5s{$word} ) ); + $local_md5s{$word} = md5_hex($word); + + # skip system headers that are missed by the compiler -MM flag + next if ( $word =~ /^\/usr\/include/ ); + next if ( $word =~ /^\/usr\/local\/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(.*)/ or abs_path($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(.*)/ or abs_path($word) =~ /^\Q$path\E(.*)/ ) { + print "SWIG Skip TRICK_SWIG_EXCLUDE: $path$1\n" if $verbose_build; + next outer; + } + } + + # separate paths in TRICK_EXT_LIB_DIRS + foreach my $path (@ext_lib_paths) { + if ( $word =~ /^\Q$path\E(.*)/ or abs_path($word) =~ /^\Q$path\E(.*)/ ) { + if ( get_containing_path( $word, @ext_lib_paths_overrides ) eq 0 ) { + print "SWIG Skip TRICK_EXT_LIB_DIRS: $path$1\n" if $verbose_build; + $ext_libs{$word} = 1; + next outer; + } + } + } + $files{$word} = 1; + } + } + my @local_ext_lib_files = sort keys %ext_libs; + my @local_files_to_process = sort keys %files; + + return ( \@local_files_to_process, \@local_ext_lib_files, \%local_md5s ); } 1 diff --git a/libexec/trick/pm/get_makefile_vars.pm b/libexec/trick/pm/get_makefile_vars.pm index e82974868..68e41cfce 100644 --- a/libexec/trick/pm/get_makefile_vars.pm +++ b/libexec/trick/pm/get_makefile_vars.pm @@ -1,5 +1,7 @@ package get_makefile_vars; +use Cwd; + use Exporter (); @ISA = qw(Exporter); @EXPORT = qw(dump_makefile_vars); @@ -8,9 +10,9 @@ use strict; use warnings; #Utility to dump specified variables from a makefile -sub dump_makefile_vars($$$@) +sub dump_makefile_vars($$$$@) { - my ($file, $build_dir, $env_ref, @vars) = @_; + my ($file, $build_dir, $env_ref, $build_dir, @vars) = @_; open my $fh, ">", "${build_dir}/get_vars.mk" or die "Could not open ${build_dir}/get_vars.mk\n"; @@ -29,19 +31,24 @@ sub dump_makefile_vars($$$@) system("make -f ${build_dir}/get_vars.mk print_vars"); } - my @newlines; + my @validlines; open (my $fi, "${build_dir}/var_dump.mk") or die "Could not open ${build_dir}/var_dump.mk: $!" ; + + my $cwd = getcwd ; while (my $line = <$fi>) { chomp $line; if(($line =~ /\Q+=\E$/) ne 1) { - push @newlines, $line; + #Identify instances of CWD, and replace with the path of the S_define + my $b4_line = $line; + $line =~ s/$build_dir/$cwd/g; + push @validlines, $line; } } open my $fj, ">", "${build_dir}/var_dump.mk" or die "Could not open ${build_dir}/var_dump.mk\n"; - foreach my $line (@newlines) + foreach my $line (@validlines) { print $fj "$line\n"; } diff --git a/libexec/trick/pm/parse_s_define.pm b/libexec/trick/pm/parse_s_define.pm index a8bdc54ba..5193e61ca 100644 --- a/libexec/trick/pm/parse_s_define.pm +++ b/libexec/trick/pm/parse_s_define.pm @@ -1,42 +1,42 @@ -package parse_s_define ; +package parse_s_define; use Exporter (); -@ISA = qw(Exporter); +@ISA = qw(Exporter); @EXPORT = qw(parse_s_define handle_sim_object handle_integ_loop handle_collects - handle_user_code handle_user_header handle_user_inline index_comments) ; + handle_user_code handle_user_header handle_user_inline index_comments); -use Cwd ; -use File::Basename ; -use strict ; +use Cwd; +use File::Basename; +use strict; use Cwd 'abs_path'; -use IPC::Open3 ; +use IPC::Open3; -use edit ; -use find_module ; -use gte ; -use trick_print ; -use trick_version ; +use edit; +use find_module; +use gte; +use trick_print; +use trick_version; use Text::Balanced qw(extract_bracketed); -use html ; -use get_paths ; +use html; +use get_paths; BEGIN { - if($ENV{'TRICK_PERL_DEBUG'} eq 1) { + if ( $ENV{'TRICK_PERL_DEBUG'} eq 1 ) { require re; re->import('debug'); } } -my ($integ_loop_def , $collect_def , $vcollect_def); -my ($job_class_order_def ) ; -my ($sim_class_def , $sim_class_job_def , $instantiation_def , $create_connections_def) ; -my ($compiler_directive_def ) ; -my ($other_tag_def , $comment_def ) ; -my ($user_code_def ) ; -my ($user_header_def ) ; -my ($user_inline_def ) ; -my ($line_tag_def) ; -my $s_define_file ; +my ( $integ_loop_def, $collect_def, $vcollect_def ); +my ($job_class_order_def); +my ( $sim_class_def, $sim_class_job_def, $instantiation_def, $create_connections_def ); +my ($compiler_directive_def); +my ( $other_tag_def, $comment_def ); +my ($user_code_def); +my ($user_header_def); +my ($user_inline_def); +my ($line_tag_def); +my $s_define_file; #------------------------------------------------------------ # IntegLoop statements @@ -61,7 +61,7 @@ $integ_loop_def = qr/ \s* (?:.*?) # name list \s*; # terminating semicolon - /sx ; + /sx; #------------------------------------------------------------ # Collect statements @@ -75,7 +75,7 @@ $collect_def = qr/ { # entry (?:.*?) # collect params }\s*; # end args - /sx ; + /sx; #------------------------------------------------------------ # Vector collect statements @@ -89,17 +89,17 @@ $vcollect_def = qr/ \{\s* # entry (?:.*?) # item list \s*\}\s*; # end args - /sx ; + /sx; $compiler_directive_def = qr/ \#\#[^\n]+ # compiler directive - /sx ; + /sx; $sim_class_def = qr/ (?:template\s+<[^>]+>\s*)? class # the keyword class [^{]+ # everything up to opening parenthesis - /sx ; + /sx; $sim_class_job_def = qr/ (?: @@ -129,51 +129,52 @@ $sim_class_job_def = qr/ \( # entry point (?:.*?)\s* # arg list \)\s*; # end arg list - /sx ; + /sx; $instantiation_def = qr/ (?:[A-Za-z_]+[\w_:\*]*(?:<[^>]+>)?)\s+ # type (?:[A-Za-z_]+[\w_]*)\s* # name (?:\(.*?;|\s*;) # arguments - /sx ; - #(?:\([^{\)]*\))?\s*; # arguments + /sx; + +#(?:\([^{\)]*\))?\s*; # arguments $create_connections_def = qr/ void\s+create_connections # create_connections declaration [^{]+ # everything up to opening parenthesis - /sx ; + /sx; $job_class_order_def = qr/ - job_class_order # the word sim_object + job_class_order\s*{ # the word sim_object (?:.*? # everything })\s*; # to end of obj def - /sx ; + /sx; $user_code_def = qr/ %\{\s* .*? %\} - /sx ; + /sx; $user_header_def = qr/ %\s*header\s*{\s* .*? %} - /sx ; + /sx; $user_inline_def = qr/ %\s*inline\s*{\s* .*? %} - /sx ; + /sx; -$other_tag_def = qr/\#(?:ident|pragma)?.*?\n/s ; -$comment_def = qr/ZZZYYYXXX\d+ZZZYYYXXX/s ; -$line_tag_def = qr/\#(?:line)?\s+\d+.*?(?:\n|$)/s ; +$other_tag_def = qr/\#(?:ident|pragma)?.*?\n/s; +$comment_def = qr/ZZZYYYXXX\d+ZZZYYYXXX/s; +$line_tag_def = qr/\#(?:line)?\s+\d+.*?(?:\n|$)/s; #checks if the line is a preprocessor include statement, and updates context sub check_for_pp_include (\$\%) { - my ($text, $context) = @_; + my ( $text, $context ) = @_; $context->{"pp_include"} = 0; @@ -184,7 +185,7 @@ sub check_for_pp_include (\$\%) { #checks if the line is either a preprocessor warning or error statement, and updates context sub check_for_pp_error (\$\%) { - my ($text, $context) = @_; + my ( $text, $context ) = @_; $context->{"pp_error"} = 0; @@ -203,18 +204,21 @@ sub check_for_pp_error (\$\%) { # And the " is not a char # Then we are entering/exiting a string sub check_for_string (\$\$\%) { - my ($line, $idx, $context) = @_; + my ( $line, $idx, $context ) = @_; my $i = $$idx; - if ( (substr $$line, $i, 1) eq "\"" and ($context->{"c_comment"} == 0) ) { + if ( ( substr $$line, $i, 1 ) eq "\"" and ( $context->{"c_comment"} == 0 ) ) { + #make sure the " is not just a char - if( (substr $$line, $i-1, 3) ne "\'\"\'" and (substr $$line, $i-1, 2) ne "\\\"") { + if ( ( substr $$line, $i - 1, 3 ) ne "\'\"\'" and ( substr $$line, $i - 1, 2 ) ne "\\\"" ) { + #found the start of a string - if($context->{"string"} == 0) { + if ( $context->{"string"} == 0 ) { $context->{"string"} = 1; } + #found the end of a string - elsif($context->{"string"} == 1) { + elsif ( $context->{"string"} == 1 ) { $context->{"string"} = 0; } } @@ -231,11 +235,15 @@ sub check_for_string (\$\$\%) { #NOTE: We do not need to track if we are in a c++ comment, because once we see one start # we can skip the rest of the line. sub check_for_cpp_comment (\$\%\@) { - my ($text, $context, $comments) = @_; + my ( $text, $context, $comments ) = @_; - if ( $$text eq "//" and ($context->{"string"} == 0) and ($context->{"c_comment"} == 0) and ($context->{"angle"} == 0) ) { + if ( $$text eq "//" + and ( $context->{"string"} == 0 ) + and ( $context->{"c_comment"} == 0 ) + and ( $context->{"angle"} == 0 ) ) + { $context->{"cpp_comment"} = 1; - push(@$comments, $context->{"idx"}); + push( @$comments, $context->{"idx"} ); } } @@ -246,15 +254,23 @@ sub check_for_cpp_comment (\$\%\@) { # And come across either a /* or */ # Then we are either entering/exiting a c comment sub check_for_c_comment (\$\%\@) { - my ($text, $context, $comments) = @_; + my ( $text, $context, $comments ) = @_; - if ( $$text eq "/*" and ($context->{"string"} == 0) and ($context->{"c_comment"} == 0) and ($context->{"angle"} == 0) ) { + if ( $$text eq "/*" + and ( $context->{"string"} == 0 ) + and ( $context->{"c_comment"} == 0 ) + and ( $context->{"angle"} == 0 ) ) + { $context->{"c_comment"} = 1; - push(@$comments, $context->{"idx"}); + push( @$comments, $context->{"idx"} ); } - elsif ( $$text eq "*/" and ($context->{"string"} == 0) and ($context->{"c_comment"} == 1) and ($context->{"angle"} == 0) ) { + elsif ( $$text eq "*/" + and ( $context->{"string"} == 0 ) + and ( $context->{"c_comment"} == 1 ) + and ( $context->{"angle"} == 0 ) ) + { $context->{"c_comment"} = 0; - push(@$comments, $context->{"idx"}+1); + push( @$comments, $context->{"idx"} + 1 ); } } @@ -266,50 +282,54 @@ sub check_for_c_comment (\$\%\@) { # And the char matches either <> # Then we are either entering/exiting the brackets of a #include<> statement sub check_for_angle_bracket (\$\%) { - my ($text, $context) = @_; + my ( $text, $context ) = @_; - if ( ($context->{"pp_include"} == 1) and ($context->{"string"} == 0) and ($context->{"c_comment"} == 0) ) { - if ( $$text eq "<" and ($context->{"angle"} == 0) ) { + if ( ( $context->{"pp_include"} == 1 ) and ( $context->{"string"} == 0 ) and ( $context->{"c_comment"} == 0 ) ) { + if ( $$text eq "<" and ( $context->{"angle"} == 0 ) ) { $context->{"angle"} = 1; } - if ( $$text eq ">" and ($context->{"angle"} == 1) ) { + if ( $$text eq ">" and ( $context->{"angle"} == 1 ) ) { $context->{"angle"} = 0; } } } -# Preprocess lines to handle line continuations so that each line that ends with +# Preprocess lines to handle line continuations so that each line that ends with # a continuation marker will be concatenated with the next line. # e.g.: "this is a line with continuation \" # "this is the next line" # The result line would be: "this is a line with continuation this is the next line" sub preprocess_lines { - my @text = @_; - my @result = (); + my @text = @_; + my @result = (); my $current_line = ""; - + foreach my $line (@text) { + # If we have a partial line, append this line to it if ($current_line) { $current_line .= $line; - } else { + } + else { $current_line = $line; } - + # Check if this line ends with a continuation marker - if ($current_line =~ s/\\\n$//){ + if ( $current_line =~ s/\\\n$// ) { + # Line continues - add two spaces and continue to next line $current_line .= " "; - } else { + } + else { # Line is complete - add to result and reset current_line push @result, $current_line; $current_line = ""; } } - + # Handle any remaining partial line push @result, $current_line if $current_line; - + return @result; } @@ -325,16 +345,11 @@ sub index_comments (@) { my $line_idx; my $each_item; my $item_length; - my %context = ( "string", 0, - "cpp_comment", 0, - "c_comment", 0, - "angle", 0, - "pp_include", 0, - "pp_error", 0, - "idx", 0 ); - - for($line_idx = 0; $line_idx < @text; ++$line_idx) { - $each_item = @text[$line_idx]; + my %context = + ( "string", 0, "cpp_comment", 0, "c_comment", 0, "angle", 0, "pp_include", 0, "pp_error", 0, "idx", 0 ); + + for ( $line_idx = 0 ; $line_idx < @text ; ++$line_idx ) { + $each_item = @text[$line_idx]; $item_length = length($each_item); #Check for specific pp directives that change comment parsing @@ -342,20 +357,22 @@ sub index_comments (@) { check_for_pp_error( $each_item, %context ); #iterate over each char - for ( my $i = 0; $i < $item_length; ++$i ) { + for ( my $i = 0 ; $i < $item_length ; ++$i ) { + # For either a c++ comment or a preprocessor error command we can skip processing the rest of the line - if($context{"cpp_comment"} == 0 and $context{"pp_error"} == 0) { + if ( $context{"cpp_comment"} == 0 and $context{"pp_error"} == 0 ) { + #checks for strings - check_for_string($each_item, $i, %context); + check_for_string( $each_item, $i, %context ); #checks for c++ style comments - check_for_cpp_comment((substr $each_item, $i, 2), %context, @comment_sections); + check_for_cpp_comment( ( substr $each_item, $i, 2 ), %context, @comment_sections ); #checks for c-style comment open or close - check_for_c_comment((substr $each_item, $i, 2), %context, @comment_sections); + check_for_c_comment( ( substr $each_item, $i, 2 ), %context, @comment_sections ); # #include <> handling - check_for_angle_bracket((substr $each_item, $i, 1), %context); + check_for_angle_bracket( ( substr $each_item, $i, 1 ), %context ); } @@ -363,9 +380,10 @@ sub index_comments (@) { } # Newline. If we were in a c++ comment, we no longer are. - if($context{"cpp_comment"} == 1) { + if ( $context{"cpp_comment"} == 1 ) { + #-2 because we're not including the newline - push(@comment_sections, $context{"idx"}-2); + push( @comment_sections, $context{"idx"} - 2 ); } $context{"cpp_comment"} = 0; } @@ -375,69 +393,77 @@ sub index_comments (@) { sub parse_s_define ($) { - my ($sim_ref) = @_ ; + my ($sim_ref) = @_; - my ($temp) ; - my ($CC, $contents) ; - my (@prescan_job_class_order) ; - my ($version, $thread, $year) ; - my @comments ; + my ($temp); + my ( $CC, $contents ); + my (@prescan_job_class_order); + my ( $version, $thread, $year ); + my @comments; my @preprocess_output; - @{$$sim_ref{inc_paths}} = (get_include_paths(), $ENV{TRICK_SYSTEM_CFLAGS} =~ /-(?:I|isystem)(\S+)/g, "$ENV{TRICK_HOME}/trick_source" , "../include") ; + @{ $$sim_ref{inc_paths} } = ( + get_include_paths(), + $ENV{TRICK_SYSTEM_CFLAGS} =~ /-(?:I|isystem)(\S+)/g, + "$ENV{TRICK_HOME}/trick_source", + "../include", $ENV{'TRICK_BUILD_DIR'} + ); - my @valid_inc_paths ; - foreach (@{$$sim_ref{inc_paths}}) { + my @valid_inc_paths; + foreach ( @{ $$sim_ref{inc_paths} } ) { - push @valid_inc_paths , $_ if ( -e $_ ) ; + push @valid_inc_paths, $_ if ( -e $_ ); } - @{$$sim_ref{inc_paths}} = @valid_inc_paths ; + @{ $$sim_ref{inc_paths} } = @valid_inc_paths; - foreach ( @valid_inc_paths ) { - $_ = abs_path($_) ; + foreach (@valid_inc_paths) { + $_ = abs_path($_); } - foreach ( @{$$sim_ref{inc_paths}} ) { - s/\/+$// ; - s/\/+/\// ; - $_ = quotemeta (abs_path(dirname($_)) . "/" . basename($_)) ; + foreach ( @{ $$sim_ref{inc_paths} } ) { + s/\/+$//; + s/\/+/\//; + $_ = quotemeta( abs_path( dirname($_) ) . "/" . basename($_) ); } - $s_define_file = "S_define" ; + $s_define_file = "$ENV{TRICK_SIM_DIR}S_define"; - $$sim_ref{line_num} = 1 ; + $$sim_ref{line_num} = 1; # Run S_define through C PreProcessor to handle #defines - $CC = gte("TRICK_CC") ; - chomp $CC ; + $CC = gte("TRICK_CC"); + chomp $CC; - if (-e $s_define_file) { + if ( -e $s_define_file ) { my $cmd; $cmd = "$CC -C -E -xc $ENV{TRICK_SFLAGS} $ENV{TRICK_SYSTEM_SFLAGS} $s_define_file"; + #print "$cmd\n" ; @preprocess_output = `$cmd`; -# The commented out code is what I would like to use, but it hangs on Macs (Alex 6/13/11) -# my($wtr, $rdr, $err); -# my($pid , @error_msg); -# use Symbol 'gensym'; $err = gensym; -# $pid = open3($wtr, $rdr, $err, $cmd); -# -# waitpid( $pid , 0 ) ; -# @preprocess_output = <$rdr> ; + # The commented out code is what I would like to use, but it hangs on Macs (Alex 6/13/11) + # my($wtr, $rdr, $err); + # my($pid , @error_msg); + # use Symbol 'gensym'; $err = gensym; + # $pid = open3($wtr, $rdr, $err, $cmd); + # + # waitpid( $pid , 0 ) ; + # @preprocess_output = <$rdr> ; - if (($? >> 8) != 0) { + if ( ( $? >> 8 ) != 0 ) { trick_print( $$sim_ref{fh}, "\nError in $s_define_file. Exit!\n\n", "title_red", $$sim_ref{args}{v} ); -# my(@error_msg); -# @error_msg = <$err> ; -# trick_print( $$sim_ref{fh}, "@error_msg\n\n", "normal_white", $$sim_ref{args}{v} ); - exit -1 ; + + # my(@error_msg); + # @error_msg = <$err> ; + # trick_print( $$sim_ref{fh}, "@error_msg\n\n", "normal_white", $$sim_ref{args}{v} ); + exit -1; } - } else { + } + else { die "Couldn't find file: $s_define_file\n"; } @@ -446,71 +472,80 @@ sub parse_s_define ($) { $contents .= $each_item; } - for(my $idx = 0 ; $idx < @comment_sections ; $idx+=2) { - my $comment_length = @comment_sections[$idx+1] - @comment_sections[$idx] + 1; - push(@comments, (substr $contents, @comment_sections[$idx], $comment_length) ); + for ( my $idx = 0 ; $idx < @comment_sections ; $idx += 2 ) { + my $comment_length = @comment_sections[ $idx + 1 ] - @comment_sections[$idx] + 1; + push( @comments, ( substr $contents, @comment_sections[$idx], $comment_length ) ); } foreach my $i (@comments) { - my %header ; - my @lib_list ; - %header = extract_trick_header("S_define", $i, 0, 0); - push @{$$sim_ref{default_data}} , $header{default_data} ; + my %header; + my @lib_list; + %header = extract_trick_header( "S_define", $i, 0, 0 ); + push @{ $$sim_ref{default_data} }, $header{default_data}; + # S_define header text keeps comment stars after html.pm flattens newlines, so remove # both whitespace and '*' before extracting the inner dependency items. - $header{libdep} =~ s/[\s\*]+//sg ; - $header{libdep} =~ s/\(\(/\(/ ; - $header{libdep} =~ s/\)\)/\)/ ; - @lib_list = $header{libdep} =~ m/\((.+?)\)/sg ; + $header{libdep} =~ s/[\s\*]+//sg; + $header{libdep} =~ s/\(\(/\(/; + $header{libdep} =~ s/\)\)/\)/; + @lib_list = $header{libdep} =~ m/\((.+?)\)/sg; + # Append any library deps in doxygen style comments. - push @lib_list , @{$header{liblist}} if ( exists $header{liblist} ) ; + push @lib_list, @{ $header{liblist} } if ( exists $header{liblist} ); foreach my $object_file (@lib_list) { + #print " look for object $object_file\n" ; if ( $object_file =~ /^\// ) { - push @{$$sim_ref{mis_entry_files}}, $object_file ; - } else { - my $found = 0 ; - foreach my $inc_path ( @valid_inc_paths ) { + push @{ $$sim_ref{mis_entry_files} }, $object_file; + } + else { + my $found = 0; + foreach my $inc_path (@valid_inc_paths) { if ( -f "$inc_path/$object_file" ) { - push @{$$sim_ref{mis_entry_files}}, "$inc_path/$object_file" ; - $found = 1 ; - last ; + push @{ $$sim_ref{mis_entry_files} }, "$inc_path/$object_file"; + $found = 1; + last; } } if ( $found == 0 ) { - trick_formatted_print($$sim_ref{fh}, "", "Warning ", "", "S_define\n", "", " Could not find dependency \"", "", "$object_file", "", "\"\n"); + trick_formatted_print( $$sim_ref{fh}, "", "Warning ", "", "S_define\n", "", + " Could not find dependency \"", + "", "$object_file", "", "\"\n" ); } } } } - my $i = (@comment_sections / 2) - 1 ; - for(my $idx = @comment_sections-2 ; $idx >= 0 ; $idx-=2) { - my $comment_length = @comment_sections[$idx+1] - @comment_sections[$idx] + 1; - substr $contents, @comment_sections[$idx], $comment_length, ("ZZZYYYXXX" . $i-- . "ZZZYYYXXX"); + my $i = ( @comment_sections / 2 ) - 1; + for ( my $idx = @comment_sections - 2 ; $idx >= 0 ; $idx -= 2 ) { + my $comment_length = @comment_sections[ $idx + 1 ] - @comment_sections[$idx] + 1; + substr $contents, @comment_sections[$idx], $comment_length, ( "ZZZYYYXXX" . $i-- . "ZZZYYYXXX" ); } # substitue in environment variables in the S_define file. # Do that with 1 line in C! This comment is longer than the code it took! - $contents =~ s/\$[({]\s*([\w_]+)\s*[)}]/$ENV{$1}/eg ; + $contents =~ s/\$[({]\s*([\w_]+)\s*[)}]/$ENV{$1}/eg; #strip trailing spaces - $contents =~ s/\s*$// ; + $contents =~ s/\s*$//; + #rip out define comments left by gcc 2.96 - $contents =~ s/\/\*.*?\*+\///sg ; + $contents =~ s/\/\*.*?\*+\///sg; - $$sim_ref{sim_class_index}{"Trick::SimObject"} = 0 ; + $$sim_ref{sim_class_index}{"Trick::SimObject"} = 0; # set the default job class order - @{$$sim_ref{user_class_order}} = qw(automatic random environment sensor sensor_emitter - sensor_reflector sensor_receiver scheduled effector - effector_emitter effector_receiver automatic_last logging - data_record system_checkpoint system_advance_sim_time - system_moding integ_loop) ; + @{ $$sim_ref{user_class_order} } = qw(automatic random environment sensor sensor_emitter + sensor_reflector sensor_receiver scheduled effector + effector_emitter effector_receiver automatic_last logging + data_record system_checkpoint system_advance_sim_time + system_moding integ_loop); + # search and use a user class order - @prescan_job_class_order = $contents =~ m/($job_class_order_def)/sg ; - preparse_job_class_order( \@prescan_job_class_order , $sim_ref ) ; + @prescan_job_class_order = $contents =~ m/($job_class_order_def)/sg; + preparse_job_class_order( \@prescan_job_class_order, $sim_ref ); - while ($contents =~ s/^(\s*)(?:($sim_class_def)| + while ( + $contents =~ s/^(\s*)(?:($sim_class_def)| ($integ_loop_def)| ($collect_def)| ($user_code_def) | @@ -524,37 +559,40 @@ sub parse_s_define ($) { ($compiler_directive_def)| ($other_tag_def)| ($comment_def) - )//sx ) { - if ( defined $1 and $1 ne "" ) { - $temp = $1 ; + )//sx + ) + { + if ( defined $1 and $1 ne "" ) { + $temp = $1; + #trick_print($$sim_ref{fh}, $temp, "debug_white" , $$sim_ref{args}{v}); - $$sim_ref{line_num} += ($temp =~ s/\n/\n/g) ; + $$sim_ref{line_num} += ( $temp =~ s/\n/\n/g ); } - if ( defined $2 and $2 ne "" ) { handle_sim_class($2, \$contents, $sim_ref, \@comments) ; } - if ( defined $3 and $3 ne "" ) { handle_integ_loop($3, $sim_ref) ; } - if ( defined $4 and $4 ne "" ) { handle_collects($4, $sim_ref) ; } - if ( defined $5 and $5 ne "" ) { handle_user_code($5, $sim_ref) ; } - if ( defined $6 and $6 ne "" ) { handle_user_header($6, $sim_ref) ; } - if ( defined $7 and $7 ne "" ) { handle_user_inline($7, $sim_ref) ; } - if ( defined $8 and $8 ne "" ) { handle_line_tag($8, $sim_ref) ; } #line tag - if ( defined $9 and $9 ne "" ) { } #job class order... preparsed - if ( defined $10 and $10 ne "" ) { handle_vcollects($10, $sim_ref) ; } - if ( defined $11 and $11 ne "" ) { handle_create_connections($11, \$contents, $sim_ref) ; } - if ( defined $12 and $12 ne "" ) { handle_instantiation($12, $sim_ref) ; } - if ( defined $13 and $13 ne "" ) { handle_compiler_directive($13, $sim_ref) ; } - if ( defined $14 and $14 ne "" ) { } #ignore these lines - } - - $contents =~ s/\cZ$//sx ; - $contents =~ s/^(\s*)//sx ; - $$sim_ref{line_num} += (($temp = $1) =~ s/\n/\n/g) ; + if ( defined $2 and $2 ne "" ) { handle_sim_class( $2, \$contents, $sim_ref, \@comments ); } + if ( defined $3 and $3 ne "" ) { handle_integ_loop( $3, $sim_ref ); } + if ( defined $4 and $4 ne "" ) { handle_collects( $4, $sim_ref ); } + if ( defined $5 and $5 ne "" ) { handle_user_code( $5, $sim_ref ); } + if ( defined $6 and $6 ne "" ) { handle_user_header( $6, $sim_ref ); } + if ( defined $7 and $7 ne "" ) { handle_user_inline( $7, $sim_ref ); } + if ( defined $8 and $8 ne "" ) { handle_line_tag( $8, $sim_ref ); } #line tag + if ( defined $9 and $9 ne "" ) { } #job class order... preparsed + if ( defined $10 and $10 ne "" ) { handle_vcollects( $10, $sim_ref ); } + if ( defined $11 and $11 ne "" ) { handle_create_connections( $11, \$contents, $sim_ref ); } + if ( defined $12 and $12 ne "" ) { handle_instantiation( $12, $sim_ref ); } + if ( defined $13 and $13 ne "" ) { handle_compiler_directive( $13, $sim_ref ); } + if ( defined $14 and $14 ne "" ) { } #ignore these lines + } + + $contents =~ s/\cZ$//sx; + $contents =~ s/^(\s*)//sx; + $$sim_ref{line_num} += ( ( $temp = $1 ) =~ s/\n/\n/g ); if ( $contents ne "" ) { - trick_print($$sim_ref{fh},"Syntax error in $$sim_ref{last_file}\n", "title_red", $$sim_ref{args}{v}) ; - my @temp_array = split /\n/ , $contents ; - my $temp = join "\n" , (splice ( @temp_array , 0 , 10 )) ; - trick_print($$sim_ref{fh},"Last 10 lines read:\n$temp\n", "title_red", $$sim_ref{args}{v}) ; - edit_and_exit("CP" , "$s_define_file" , $$sim_ref{line_num} ) ; + trick_print( $$sim_ref{fh}, "Syntax error in $$sim_ref{last_file}\n", "title_red", $$sim_ref{args}{v} ); + my @temp_array = split /\n/, $contents; + my $temp = join "\n", ( splice( @temp_array, 0, 10 ) ); + trick_print( $$sim_ref{fh}, "Last 10 lines read:\n$temp\n", "title_red", $$sim_ref{args}{v} ); + edit_and_exit( "CP", "$s_define_file", $$sim_ref{line_num} ); } } @@ -562,14 +600,14 @@ sub parse_s_define ($) { # Handle Integration Loop Statements sub handle_integ_loop ($$) { - my ($integ_loop, $sim_ref) = @_ ; - my ($child_spec, $name, $cycle, $name_list ) ; - my %integ_loop_info ; + my ( $integ_loop, $sim_ref ) = @_; + my ( $child_spec, $name, $cycle, $name_list ); + my %integ_loop_info; - trick_print($$sim_ref{fh}, "IntegLoop: $integ_loop\n" , "debug_white" , $$sim_ref{args}{v}); + trick_print( $$sim_ref{fh}, "IntegLoop: $integ_loop\n", "debug_white", $$sim_ref{args}{v} ); # remove all comments - $integ_loop =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//g ; + $integ_loop =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//g; ( $child_spec, $name, $cycle, $name_list ) = $integ_loop =~ / (?:IntegLoop|integrate) # IntegLoop keyword @@ -585,30 +623,31 @@ sub handle_integ_loop ($$) { \s* (.*?) # name list \s*; # terminating semicolon - /sx ; + /sx; - $integ_loop_info{name} = $name ; - $integ_loop_info{cycle} = $cycle ; - $child_spec = 0 if ( $child_spec eq "" ) ; - $integ_loop_info{child} = $child_spec ; -# @{$integ_loop_info{name_list}} = split(/\s*,\s*/, $name_list ); - $integ_loop_info{name_list} = $name_list ; - $integ_loop_info{line_num} = $$sim_ref{line_num} ; + $integ_loop_info{name} = $name; + $integ_loop_info{cycle} = $cycle; + $child_spec = 0 if ( $child_spec eq "" ); + $integ_loop_info{child} = $child_spec; - push @{$$sim_ref{integ_loop}}, \%integ_loop_info ; + # @{$integ_loop_info{name_list}} = split(/\s*,\s*/, $name_list ); + $integ_loop_info{name_list} = $name_list; + $integ_loop_info{line_num} = $$sim_ref{line_num}; - $$sim_ref{line_num} += ($integ_loop =~ s/\n/\n/g) ; + push @{ $$sim_ref{integ_loop} }, \%integ_loop_info; + + $$sim_ref{line_num} += ( $integ_loop =~ s/\n/\n/g ); } # Handle Collect Statements sub handle_collects ($$) { - my ( $collect , $sim_ref ) = @_ ; - my ( $collect_name, $collect_params ) ; - my %collect_info ; + my ( $collect, $sim_ref ) = @_; + my ( $collect_name, $collect_params ); + my %collect_info; - trick_print($$sim_ref{fh}, "Collect: $collect\n" , "debug_white" , $$sim_ref{args}{v}); + trick_print( $$sim_ref{fh}, "Collect: $collect\n", "debug_white", $$sim_ref{args}{v} ); ( $collect_name, $collect_params ) = $collect =~ / collect # Collect keyword \s* @@ -619,31 +658,31 @@ sub handle_collects ($$) { {\s* # entry (.*?) # collect params }\s*; # end args - /sx ; - # Setup collect params for a split (take out newlines and lead/trail space) - $collect_params =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//g ; - $collect_params =~ s,\n|^\s*|\s*$,,g ; + /sx; - $collect_info{name} = $collect_name ; - @{$collect_info{params}} = split(/\s*,\s*/ , $collect_params ) ; - $collect_info{num_params} = $#{$collect_info{params}} + 1 ; + # Setup collect params for a split (take out newlines and lead/trail space) + $collect_params =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//g; + $collect_params =~ s,\n|^\s*|\s*$,,g; - push @{$$sim_ref{collect}} , \%collect_info ; + $collect_info{name} = $collect_name; + @{ $collect_info{params} } = split( /\s*,\s*/, $collect_params ); + $collect_info{num_params} = $#{ $collect_info{params} } + 1; + push @{ $$sim_ref{collect} }, \%collect_info; - $$sim_ref{line_num} += ($collect =~ s/\n/\n/g) ; + $$sim_ref{line_num} += ( $collect =~ s/\n/\n/g ); } # Handle Vcollect Statements sub handle_vcollects ($$) { - my ( $vcollect , $sim_ref ) = @_ ; + my ( $vcollect, $sim_ref ) = @_; my ( $container_name, $constructor, $item_list ); - my %collect_info ; + my %collect_info; - trick_print($$sim_ref{fh}, "Vcollect: $vcollect\n" , "debug_white" , $$sim_ref{args}{v}) ; + trick_print( $$sim_ref{fh}, "Vcollect: $vcollect\n", "debug_white", $$sim_ref{args}{v} ); - $vcollect =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//g ; + $vcollect =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//g; ( $container_name, $constructor, $item_list ) = $vcollect =~ / vcollect # Vcollect keyword @@ -655,112 +694,115 @@ sub handle_vcollects ($$) { {\s* # entry (.*?) # item list \s*}\s* # end args - /sx ; + /sx; + # Setup collect params for a split (take out newlines and lead/trail spaces) - $item_list =~ s,\n|^\s*|\s*$,,g ; + $item_list =~ s,\n|^\s*|\s*$,,g; - $collect_info{name} = $container_name ; - $collect_info{constructor} = $constructor ; - @{$collect_info{items}} = split(/\s*, \s*/ , $item_list) ; + $collect_info{name} = $container_name; + $collect_info{constructor} = $constructor; + @{ $collect_info{items} } = split( /\s*, \s*/, $item_list ); - push @{$$sim_ref{vcollect}} , \%collect_info ; + push @{ $$sim_ref{vcollect} }, \%collect_info; - $$sim_ref{line_num} += ($vcollect =~ s/\n/\n/g) ; + $$sim_ref{line_num} += ( $vcollect =~ s/\n/\n/g ); } # Handle User code on Statements sub handle_user_code ($$) { - my ($u, $sim_ref) = @_ ; + my ( $u, $sim_ref ) = @_; - trick_print($$sim_ref{fh}, "User code: $u\n" , "debug_white" , $$sim_ref{args}{v}); - $$sim_ref{line_num} += ($u =~ s/\n/\n/g) ; - $u =~ s/^##/#/mg ; - $u =~ /%\{(.*?)%\}/s ; - $u = $1 ; - $u =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//g ; - $$sim_ref{user_code} .= $u ; + trick_print( $$sim_ref{fh}, "User code: $u\n", "debug_white", $$sim_ref{args}{v} ); + $$sim_ref{line_num} += ( $u =~ s/\n/\n/g ); + $u =~ s/^##/#/mg; + $u =~ /%\{(.*?)%\}/s; + $u = $1; + $u =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//g; + $$sim_ref{user_code} .= $u; } sub handle_user_header ($$) { - my ($u, $sim_ref) = @_ ; + my ( $u, $sim_ref ) = @_; - trick_print($$sim_ref{fh}, "User header: $u\n" , "debug_white" , $$sim_ref{args}{v}); + trick_print( $$sim_ref{fh}, "User header: $u\n", "debug_white", $$sim_ref{args}{v} ); - $$sim_ref{line_num} += ($u =~ s/\n/\n/g) ; - $u =~ s/^##/#/mg ; - $u =~ /%\s*header\s*{(.*?)%}/s ; - $u = $1 ; - $u =~ s/^#\s+(\d+)\s+"S_define"\n//mg ; - $u =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//esg ; - $$sim_ref{user_header} .= $u ; + $$sim_ref{line_num} += ( $u =~ s/\n/\n/g ); + $u =~ s/^##/#/mg; + $u =~ /%\s*header\s*{(.*?)%}/s; + $u = $1; + $u =~ s/^#\s+(\d+)\s+"S_define"\n//mg; + $u =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//esg; + $$sim_ref{user_header} .= $u; } sub handle_user_inline ($$) { - my ($u, $sim_ref) = @_ ; + my ( $u, $sim_ref ) = @_; - trick_print($$sim_ref{fh}, "Inline code: $u\n" , "debug_white" , $$sim_ref{args}{v}); + trick_print( $$sim_ref{fh}, "Inline code: $u\n", "debug_white", $$sim_ref{args}{v} ); - $$sim_ref{line_num} += ($u =~ s/\n/\n/g) ; - $u =~ s/^##/#/mg ; - $u =~ /%\s*inline\s*{(.*?)%}/s ; - $u = $1 ; - $u =~ s/^#\s+(\d+)\s+"S_define"\n//mg ; - $u =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//esg ; - $$sim_ref{sim_class_code} .= $u ; - $$sim_ref{sim_class_code} .= "\n" ; + $$sim_ref{line_num} += ( $u =~ s/\n/\n/g ); + $u =~ s/^##/#/mg; + $u =~ /%\s*inline\s*{(.*?)%}/s; + $u = $1; + $u =~ s/^#\s+(\d+)\s+"S_define"\n//mg; + $u =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//esg; + $$sim_ref{sim_class_code} .= $u; + $$sim_ref{sim_class_code} .= "\n"; } sub handle_sim_class ($$$$) { - my ($s, $file_contents, $sim_ref, $comments_ref) = @_; - my ($full_template_args, $template_args) ; - my ($class_contents , $constructor_contents) ; - my ($class_name , $base_clause) ; - my $final_contents ; - my $int_call_functions ; - my $double_call_functions ; - my $constructor_found = 0 ; - my $job ; + my ( $s, $file_contents, $sim_ref, $comments_ref ) = @_; + my ( $full_template_args, $template_args ); + my ( $class_contents, $constructor_contents ); + my ( $class_name, $base_clause ); + my $final_contents; + my $int_call_functions; + my $double_call_functions; + my $constructor_found = 0; + my $job; + #my ($start_index, $ii) ; - my ($constructor_declare, $temp_content) ; - my ($job_push , $job_call, $is_dynamic_event) ; + my ( $constructor_declare, $temp_content ); + my ( $job_push, $job_call, $is_dynamic_event ); # remove any comments on the class definition line - $s =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//esg ; + $s =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//esg; # grab the class name and the name of the class we are inheriting from - ($full_template_args, $class_name, $base_clause) = $s =~ /(?:\s*template\s*<\s*([^>]+?)\s*>)?\s*class\s+(\w+)\s*(?::\s*(.+?)\s*)?$/ ; + ( $full_template_args, $class_name, $base_clause ) = + $s =~ /(?:\s*template\s*<\s*([^>]+?)\s*>)?\s*class\s+(\w+)\s*(?::\s*(.+?)\s*)?$/; - $template_args = $full_template_args ; - $template_args =~ s/class|typename//g ; - $template_args =~ s/\s//g ; + $template_args = $full_template_args; + $template_args =~ s/class|typename//g; + $template_args =~ s/\s//g; - trick_print($$sim_ref{fh}, "Processing " , "normal_blue" , $$sim_ref{args}{v}); - trick_print($$sim_ref{fh}, "$class_name\n" , "normal_white" , $$sim_ref{args}{v}); + trick_print( $$sim_ref{fh}, "Processing ", "normal_blue", $$sim_ref{args}{v} ); + trick_print( $$sim_ref{fh}, "$class_name\n", "normal_white", $$sim_ref{args}{v} ); # grab the entire contents of the class out of the S_define file. - ($class_contents, $$file_contents) = extract_bracketed($$file_contents,"{}"); - $class_contents =~ s/$line_tag_def//g ; - $$file_contents =~ s/^\s*;\s*//s ; + ( $class_contents, $$file_contents ) = extract_bracketed( $$file_contents, "{}" ); + $class_contents =~ s/$line_tag_def//g; + $$file_contents =~ s/^\s*;\s*//s; #final_contents contains the processed class. Start if off with the incoming class name - $final_contents = $s ; + $final_contents = $s; # remove all whitespace from the base-clause to simplify regex patterns $base_clause =~ s/\s//g; - # This is the full regex for matching (I hope) any valid string following the ':' in a class - # declaration. (?1) is the syntax for recursive matching, which handles arbitrarily deeply - # nested template brackets. There are only two capture groups (the other groups are non- - # capturing). Because a class can inherit from any number of parents, the second group is - # repeated wth the * operator. Unfortunately, only the final capture is retained (until - # Perl 6), so we can't actually use this regex to capture all the parents. We could use it - # to validate the string, but the compiler is going to do that anyway. - #my @parents = $base_clause =~ /^(?:private|protected|public|virtual)*([\w:]+(?:<(?:[^<>]|(?1))*>)?)(?:,(?:private|protected|public)?((?1)))*$/; +# This is the full regex for matching (I hope) any valid string following the ':' in a class +# declaration. (?1) is the syntax for recursive matching, which handles arbitrarily deeply +# nested template brackets. There are only two capture groups (the other groups are non- +# capturing). Because a class can inherit from any number of parents, the second group is +# repeated wth the * operator. Unfortunately, only the final capture is retained (until +# Perl 6), so we can't actually use this regex to capture all the parents. We could use it +# to validate the string, but the compiler is going to do that anyway. +#my @parents = $base_clause =~ /^(?:private|protected|public|virtual)*([\w:]+(?:<(?:[^<>]|(?1))*>)?)(?:,(?:private|protected|public)?((?1)))*$/; # This regex is less strict and will accept some invalid strings, but it will capture all # of the parents. Since the compiler will eventually flag any syntax errors, I think it's @@ -769,9 +811,10 @@ sub handle_sim_class ($$$$) { my $sim_object_parent; foreach (@parents) { + # remove template arguments ($_) = $_ =~ /([^<]+)/; - if (exists $$sim_ref{sim_class_index}{$_}) { + if ( exists $$sim_ref{sim_class_index}{$_} ) { $sim_object_parent = $_; last; } @@ -779,54 +822,59 @@ sub handle_sim_class ($$$$) { # if this class is not a SimObject pass it whole to S_Source.cpp if ( !$sim_object_parent ) { - $class_contents =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX/@$comments_ref[$1]/g ; - $final_contents .= "$class_contents ;\n\n" ; - $$sim_ref{sim_class_code} .= $final_contents ; - return ; + $class_contents =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX/@$comments_ref[$1]/g; + $final_contents .= "$class_contents ;\n\n"; + $$sim_ref{sim_class_code} .= $final_contents; + return; } if ( $full_template_args eq "" ) { - $int_call_functions = "int ${class_name}" ; - } else { - $int_call_functions = "template <$full_template_args> int $class_name<$template_args>" ; + $int_call_functions = "int ${class_name}"; + } + else { + $int_call_functions = "template <$full_template_args> int $class_name<$template_args>"; } - $int_call_functions .= "::call_function ( Trick::JobData * curr_job ) {\n\n int trick_ret = 0 ;\n" ; - $int_call_functions .= " if ( curr_job->disabled ) return (trick_ret) ;\n\n" ; - $int_call_functions .= " switch ( curr_job->id ) {\n" ; + $int_call_functions .= "::call_function ( Trick::JobData * curr_job ) {\n\n int trick_ret = 0 ;\n"; + $int_call_functions .= " if ( curr_job->disabled ) return (trick_ret) ;\n\n"; + $int_call_functions .= " switch ( curr_job->id ) {\n"; if ( $full_template_args eq "" ) { - $double_call_functions = "double ${class_name}" ; - } else { - $double_call_functions = "template <$full_template_args> double $class_name<$template_args>" ; + $double_call_functions = "double ${class_name}"; } - $double_call_functions .= "::call_function_double ( Trick::JobData * curr_job ) {\n\n" ; - $double_call_functions .= " double trick_ret = 0.0 ;\n" ; - $double_call_functions .= " if ( curr_job->disabled ) return (trick_ret) ;\n\n" ; - $double_call_functions .= " switch ( curr_job->id ) {\n" ; + else { + $double_call_functions = "template <$full_template_args> double $class_name<$template_args>"; + } + $double_call_functions .= "::call_function_double ( Trick::JobData * curr_job ) {\n\n"; + $double_call_functions .= " double trick_ret = 0.0 ;\n"; + $double_call_functions .= " if ( curr_job->disabled ) return (trick_ret) ;\n\n"; + $double_call_functions .= " switch ( curr_job->id ) {\n"; - $$sim_ref{sim_class_index}{$class_name} = $$sim_ref{sim_class_index}{$sim_object_parent} ; + $$sim_ref{sim_class_index}{$class_name} = $$sim_ref{sim_class_index}{$sim_object_parent}; # look for constructor while ( $class_contents =~ /^(.*?)$class_name\s*\([^;]*{/s ) { - my (@int_job_calls, @double_job_calls) ; - $constructor_found = 1 ; + my ( @int_job_calls, @double_job_calls ); + $constructor_found = 1; + # grab the constructor's argument list - $class_contents =~ s/^(.*?$class_name[^(]*)//s ; - $temp_content = $1 ; - $final_contents .= $temp_content ; - ($temp_content, $class_contents) = extract_bracketed($class_contents,"()"); - $final_contents .= $temp_content ; + $class_contents =~ s/^(.*?$class_name[^(]*)//s; + $temp_content = $1; + $final_contents .= $temp_content; + ( $temp_content, $class_contents ) = extract_bracketed( $class_contents, "()" ); + $final_contents .= $temp_content; + # a colon after the constructor arguments starts a member initializer list - if ( $class_contents =~ /^\s*:/s ) - { - my $in_init_list = 1 ; - while ( $in_init_list ) { - $class_contents =~ s/^([^{(]+)//s ; - $temp_content = $1 ; - $final_contents .= $temp_content ; + if ( $class_contents =~ /^\s*:/s ) { + my $in_init_list = 1; + while ($in_init_list) { + $class_contents =~ s/^([^{(]+)//s; + $temp_content = $1; + $final_contents .= $temp_content; + # member initializers can have either parentheses or curly braces - ($temp_content, $class_contents) = extract_bracketed($class_contents,"(){}"); - $final_contents .= $temp_content ; + ( $temp_content, $class_contents ) = extract_bracketed( $class_contents, "(){}" ); + $final_contents .= $temp_content; + # there's another initializer if there is a comma if ( $class_contents !~ /^\s*,/ ) { $in_init_list = 0; @@ -834,133 +882,152 @@ sub handle_sim_class ($$$$) { } } - $class_contents =~ s/^([^{]*)//s ; - $temp_content = $1 ; - $final_contents .= $temp_content ; + $class_contents =~ s/^([^{]*)//s; + $temp_content = $1; + $final_contents .= $temp_content; - ($constructor_contents, $class_contents) = extract_bracketed($class_contents,"{}"); + ( $constructor_contents, $class_contents ) = extract_bracketed( $class_contents, "{}" ); - $constructor_contents =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//g ; - trick_print($$sim_ref{fh}, " Constructor found\n" , "debug_white" , $$sim_ref{args}{v}); + $constructor_contents =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//g; + trick_print( $$sim_ref{fh}, " Constructor found\n", "debug_white", $$sim_ref{args}{v} ); + + $constructor_contents =~ s/\{(\s+)/\{\n Trick::JobData * job __attribute__((unused)) ;\n/; + +#$constructor_contents =~ s/\{(\s+)/\{$1int ii __attribute__ ((unused)) = $$sim_ref{sim_class_index}{$class_name} ;\n/ ; + while ( $constructor_contents =~ s/^(.*?)($sim_class_job_def)//s ) { + $final_contents .= $1; + $job = $2; - $constructor_contents =~ s/\{(\s+)/\{\n Trick::JobData * job __attribute__((unused)) ;\n/ ; - #$constructor_contents =~ s/\{(\s+)/\{$1int ii __attribute__ ((unused)) = $$sim_ref{sim_class_index}{$class_name} ;\n/ ; - while ($constructor_contents =~ s/^(.*?)($sim_class_job_def)//s ) { - $final_contents .= $1 ; - $job = $2 ; # check to see if what we matched is actually a placement new statement. if ( $final_contents !~ /new\s*$/ ) { + # Not a placement new statement. - trick_print($$sim_ref{fh}, " Job found $job\n" , "debug_white" , $$sim_ref{args}{v}); - ($job_push , $job_call , $is_dynamic_event) = handle_sim_class_job($job, $$sim_ref{sim_class_index}{$class_name}, $sim_ref ) ; - $final_contents .= "\n $job_push" ; + trick_print( $$sim_ref{fh}, " Job found $job\n", "debug_white", $$sim_ref{args}{v} ); + ( $job_push, $job_call, $is_dynamic_event ) = + handle_sim_class_job( $job, $$sim_ref{sim_class_index}{$class_name}, $sim_ref ); + $final_contents .= "\n $job_push"; if ( $is_dynamic_event == 1 ) { - push @double_job_calls , $job_call ; - $double_call_functions .= " case $$sim_ref{sim_class_index}{$class_name}:\n trick_ret = $job_call ;\n break ;\n" ; - } else { - push @int_job_calls , $job_call ; - $int_call_functions .= " case $$sim_ref{sim_class_index}{$class_name}:\n $job_call ;\n break ;\n" ; + push @double_job_calls, $job_call; + $double_call_functions .= + " case $$sim_ref{sim_class_index}{$class_name}:\n trick_ret = $job_call ;\n break ;\n"; } - $$sim_ref{sim_class_index}{$class_name}++ ; - } else { + else { + push @int_job_calls, $job_call; + $int_call_functions .= + " case $$sim_ref{sim_class_index}{$class_name}:\n $job_call ;\n break ;\n"; + } + $$sim_ref{sim_class_index}{$class_name}++; + } + else { # Is a placement new statement. Just copy contents to final_contents. - $final_contents .= $job ; + $final_contents .= $job; } } - $final_contents .= $constructor_contents ; + $final_contents .= $constructor_contents; } if ( $constructor_found == 1 ) { # if there is an inherited base class then the job id may reside in the base class if ( $sim_object_parent eq "Trick::SimObject" or $sim_object_parent eq "SimObject" ) { - $int_call_functions .= " default:\n trick_ret = -1 ;\n break ;\n" ; - $double_call_functions .= " default:\n trick_ret = 0.0 ;\n break ;\n" ; - } else { - $int_call_functions .= " default:\n trick_ret = ${sim_object_parent}::call_function( curr_job ) ;\n break ;\n" ; - $double_call_functions .= " default:\n trick_ret = ${sim_object_parent}::call_function_double( curr_job ) ;\n break ;\n" ; + $int_call_functions .= " default:\n trick_ret = -1 ;\n break ;\n"; + $double_call_functions .= " default:\n trick_ret = 0.0 ;\n break ;\n"; + } + else { + $int_call_functions .= + " default:\n trick_ret = ${sim_object_parent}::call_function( curr_job ) ;\n break ;\n"; + $double_call_functions .= + " default:\n trick_ret = ${sim_object_parent}::call_function_double( curr_job ) ;\n break ;\n"; } - $int_call_functions .= " }\n\n return(trick_ret) ;\n}\n\n" ; - $double_call_functions .= " }\n\n return(trick_ret) ;\n}\n\n" ; + $int_call_functions .= " }\n\n return(trick_ret) ;\n}\n\n"; + $double_call_functions .= " }\n\n return(trick_ret) ;\n}\n\n"; #TODO: This section should probably go into s_source.pm - $final_contents .= "\n\n public:\n" ; - $final_contents .= " virtual int call_function( Trick::JobData * curr_job ) ;\n" ; - $final_contents .= " virtual double call_function_double( Trick::JobData * curr_job ) ;\n" ; - $final_contents .= "$class_contents ;\n\n" ; + $final_contents .= "\n\n public:\n"; + $final_contents .= " virtual int call_function( Trick::JobData * curr_job ) ;\n"; + $final_contents .= " virtual double call_function_double( Trick::JobData * curr_job ) ;\n"; + $final_contents .= "$class_contents ;\n\n"; #print "$final_contents\n" ; - $final_contents =~ s/^##/#/mg ; + $final_contents =~ s/^##/#/mg; #$contents =~ s/\/\*(.*?)\*\/|\/\/(.*?)(\n)/"" . $i++ . " " . ((defined $3) ? $3 : "")/esg ; - $final_contents =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX/@$comments_ref[$1]/esg ; - - $$sim_ref{sim_class_code} .= $final_contents ; - $$sim_ref{sim_class_call_functions} .= $int_call_functions . $double_call_functions ; - } else { - $s =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX/@$comments_ref[$1]/esg ; - $$sim_ref{sim_class_code} .= $s ; - $class_contents =~ s/}\s*$// ; - $class_contents .= "\n\n public:\n" ; - $class_contents .= " virtual int call_function( Trick::JobData * curr_job ) ;\n" ; - $class_contents .= " virtual double call_function_double( Trick::JobData * curr_job ) ;\n" ; - $class_contents .= "} ;\n\n" ; - $class_contents =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX/@$comments_ref[$1]/esg ; - $$sim_ref{sim_class_code} .= $class_contents ; + $final_contents =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX/@$comments_ref[$1]/esg; + + $$sim_ref{sim_class_code} .= $final_contents; + $$sim_ref{sim_class_call_functions} .= $int_call_functions . $double_call_functions; + } + else { + $s =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX/@$comments_ref[$1]/esg; + $$sim_ref{sim_class_code} .= $s; + $class_contents =~ s/}\s*$//; + $class_contents .= "\n\n public:\n"; + $class_contents .= " virtual int call_function( Trick::JobData * curr_job ) ;\n"; + $class_contents .= " virtual double call_function_double( Trick::JobData * curr_job ) ;\n"; + $class_contents .= "} ;\n\n"; + $class_contents =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX/@$comments_ref[$1]/esg; + $$sim_ref{sim_class_code} .= $class_contents; if ( $full_template_args eq "" ) { - $int_call_functions = "int ${class_name}" ; - $double_call_functions = "double ${class_name}" ; - } else { - $int_call_functions = "template <$full_template_args> int ${class_name}<$template_args>" ; - $double_call_functions = "template <$full_template_args> double ${class_name}<$template_args>" ; + $int_call_functions = "int ${class_name}"; + $double_call_functions = "double ${class_name}"; } - $int_call_functions .= "::call_function ( Trick::JobData * curr_job __attribute__ ((unused)) ) {return 0;}\n" ; - $double_call_functions .= "::call_function_double ( Trick::JobData * curr_job __attribute__ ((unused)) ) {return 0.0;}\n" ; - $$sim_ref{sim_class_call_functions} .= $int_call_functions . $double_call_functions ; + else { + $int_call_functions = "template <$full_template_args> int ${class_name}<$template_args>"; + $double_call_functions = "template <$full_template_args> double ${class_name}<$template_args>"; + } + $int_call_functions .= "::call_function ( Trick::JobData * curr_job __attribute__ ((unused)) ) {return 0;}\n"; + $double_call_functions .= + "::call_function_double ( Trick::JobData * curr_job __attribute__ ((unused)) ) {return 0.0;}\n"; + $$sim_ref{sim_class_call_functions} .= $int_call_functions . $double_call_functions; } } sub handle_sim_class_job($$$) { - my ($in_job, $job_id, $sim_ref) = @_ ; - my ($job_push, $is_dynamic_event) ; - my ( $child, $phase, $cycle, $start, $stop, $ov_class , - $ov_class_self, $sup_class_data, $tag, $job_call, $job_ret, $job_name, $args , $class ) ; - my (@tags) ; + my ( $in_job, $job_id, $sim_ref ) = @_; + my ( $job_push, $is_dynamic_event ); + my ( $child, $phase, $cycle, $start, $stop, $ov_class, + $ov_class_self, $sup_class_data, $tag, $job_call, $job_ret, $job_name, $args, $class ); + my (@tags); # Split to 3 sections: first part (child, phase, tag), second part (timing spec), remaining part (job call) - my ($first_part, $second_part, $remaining_part) = ('', '', ''); + my ( $first_part, $second_part, $remaining_part ) = ( '', '', '' ); - if ($in_job =~ /^((?:[^(]|\n)*)?\s*(\((?:[^)]|\n)+\))\s*(.+)$/s) { - $first_part = $1; - $second_part = $2; + if ( $in_job =~ /^((?:[^(]|\n)*)?\s*(\((?:[^)]|\n)+\))\s*(.+)$/s ) { + $first_part = $1; + $second_part = $2; $remaining_part = $3; } # Extract child, phase, and tag specs from first part if they exist (can appear in any order) # First extract job tag to avoid conflicts with child/phase parsing - if ($first_part =~ /\{([\w_.,\s]+)\}/) { + if ( $first_part =~ /\{([\w_.,\s]+)\}/ ) { $tag = $1; } + # Remove tags from first_part before parsing child/phase to avoid conflicts my $first_part_no_tag = $first_part; $first_part_no_tag =~ s/\{[\w_.,\s]+\}//g; + # Extract phase first (must be at word boundary or start of string) - if ($first_part_no_tag =~ /(?:^|\s)([Pp][\w.\-\>]+)(?:\s|$)/) { + if ( $first_part_no_tag =~ /(?:^|\s)([Pp][\w.\-\>]+)(?:\s|$)/ ) { $phase = $1; + # Remove the phase from the string to avoid child extraction conflicts $first_part_no_tag =~ s/(?:^|\s)[Pp][\w.\-\>]+(?:\s|$)//; } - # Extract child (must be at word boundary or start of string) - if ($first_part_no_tag =~ /(?:^|\s)([Cc][\w.\-\>]+)(?:\s|$)/) { + + # Extract child (must be at word boundary or start of string) + if ( $first_part_no_tag =~ /(?:^|\s)([Cc][\w.\-\>]+)(?:\s|$)/ ) { $child = $1; } # Extract timing spec from second part if it exists # Format: ([, [, [,]]] ) - if ($second_part =~ /^\(\s* + if ( + $second_part =~ /^\(\s* (?: ([\w.]+) # $1: $cycle (?:\s*,\s*([\w.]+))? # $2: $start_time OR job_class (if only 2 params) @@ -971,108 +1038,122 @@ sub handle_sim_class_job($$$) { ("?[\w.]+"?) # $6: $ov_class_self (job class by itself) (?:\s*,\s*(&[\w.\-\>]+))? # $7: $sub_class_data (integration object, starts with &) ) - \s*\)/xs) { - $cycle = $1 // ''; - my $second_param = $2 // ''; - my $third_param = $3 // ''; - $ov_class = $4 // ''; - $ov_class_self = $6 // ''; - $sup_class_data = $5 // $7 // ''; - - # Determine parameter assignment based on count - if ($second_param ne '' && $third_param eq '' && $ov_class eq '' && $ov_class_self eq '') { - # Two parameters: (cycle, job_class) - $start = ''; - $stop = ''; - $ov_class = $second_param; - } elsif ($second_param ne '' && $third_param ne '' && $ov_class eq '' && $ov_class_self eq '') { - # Three parameters: (cycle, start_time, job_class) - $start = $second_param; - $stop = ''; - $ov_class = $third_param; - } else { - # Four or more parameters: (cycle, start_time, stop_time, job_class, ...) - $start = $second_param; - $stop = $third_param; - # $ov_class already set from $4 - } + \s*\)/xs + ) + { + $cycle = $1 // ''; + my $second_param = $2 // ''; + my $third_param = $3 // ''; + $ov_class = $4 // ''; + $ov_class_self = $6 // ''; + $sup_class_data = $5 // $7 // ''; + + # Determine parameter assignment based on count + if ( $second_param ne '' && $third_param eq '' && $ov_class eq '' && $ov_class_self eq '' ) { + + # Two parameters: (cycle, job_class) + $start = ''; + $stop = ''; + $ov_class = $second_param; + } + elsif ( $second_param ne '' && $third_param ne '' && $ov_class eq '' && $ov_class_self eq '' ) { + + # Three parameters: (cycle, start_time, job_class) + $start = $second_param; + $stop = ''; + $ov_class = $third_param; + } + else { + # Four or more parameters: (cycle, start_time, stop_time, job_class, ...) + $start = $second_param; + $stop = $third_param; + + # $ov_class already set from $4 + } } - if ($remaining_part =~ /\s* + if ( + $remaining_part =~ /\s* (?:\{([\w_.,\s]+)\}\s*)? # optional tag spec ( # job call ([A-Za-z_][\w\.\-\>]*\s*=)?\s* # optional return assignment variable ([A-Za-z_][\w\.\:\-\>\[\]]*)\s* # job name \((.*?)\s*\) # arg list )\s*; # end job call - /xs ) { - my $temp_tag = $1 // ''; - $job_call = $2; - $job_ret = $3 // ''; - $job_name = $4; - $args = $5; - - # If tag found in remaining_part and not already set from first_part, use it - if ($temp_tag ne '' && $tag eq '') { - $tag = $temp_tag; - } + /xs + ) + { + my $temp_tag = $1 // ''; + $job_call = $2; + $job_ret = $3 // ''; + $job_name = $4; + $args = $5; + + # If tag found in remaining_part and not already set from first_part, use it + if ( $temp_tag ne '' && $tag eq '' ) { + $tag = $temp_tag; + } } + $child = 0 if ( $child eq "" ); + $child =~ s/^C//; - $child = 0 if ( $child eq "" ) ; - $child =~ s/^C// ; - - $cycle = 1.0 if ( $cycle eq "" ) ; + $cycle = 1.0 if ( $cycle eq "" ); if ( $ov_class ne "" ) { - $class = $ov_class ; - } else { - $class = $ov_class_self ; + $class = $ov_class; + } + else { + $class = $ov_class_self; } - if ($sup_class_data eq "") { + if ( $sup_class_data eq "" ) { $sup_class_data = "NULL"; } if ( $class =~ /dynamic_event/ ) { - $is_dynamic_event = 1 ; - } else { - $is_dynamic_event = 0 ; + $is_dynamic_event = 1; + } + else { + $is_dynamic_event = 0; } if ( $tag ne "" ) { - $tag =~ s/\s+//g ; - @tags = split /,/ , $tag ; + $tag =~ s/\s+//g; + @tags = split /,/, $tag; } + # do not remove "this->", see issue #532 - $job_push = "job = this->add_job($child, $job_id, $class, $sup_class_data, $cycle, \"$job_name\", \"\"" ; + $job_push = "job = this->add_job($child, $job_id, $class, $sup_class_data, $cycle, \"$job_name\", \"\""; if ( $class =~ /^integration$/ ) { - if ($job_ret !~ /trick_ret/ ) { - $job_call = "trick_ret = " . $job_call ; + if ( $job_ret !~ /trick_ret/ ) { + $job_call = "trick_ret = " . $job_call; } } if ( $phase ne "" ) { - $phase =~ s/^P// ; - $job_push .= ", $phase" ; - } else { - $job_push .= ", 60000" ; + $phase =~ s/^P//; + $job_push .= ", $phase"; + } + else { + $job_push .= ", 60000"; } if ( $start ne "" ) { - $job_push .= ", $start" ; + $job_push .= ", $start"; } if ( $stop ne "" ) { - $job_push .= ", $stop" ; + $job_push .= ", $stop"; } - $job_push .= ") ;" ; + $job_push .= ") ;"; - foreach my $t ( @tags ) { - $job_push .= "\n " ; - $job_push .= "job->add_tag(\"$t\") ;" ; + foreach my $t (@tags) { + $job_push .= "\n "; + $job_push .= "job->add_tag(\"$t\") ;"; } - trick_print($$sim_ref{fh}," Job deconstruction: + trick_print( + $$sim_ref{fh}, " Job deconstruction: Job_id: $job_id Child: $child Phase: $phase @@ -1082,191 +1163,209 @@ sub handle_sim_class_job($$$) { Cycle: $cycle Start: $start Stop: $stop - Job name: $job_name\n", "debug_white", $$sim_ref{args}{v}) ; + Job name: $job_name\n", "debug_white", $$sim_ref{args}{v} + ); - return $job_push , $job_call , $is_dynamic_event ; + return $job_push, $job_call, $is_dynamic_event; } sub handle_instantiation ($$) { - my ($s, $sim_ref) = @_; - my ($type , $name) ; + my ( $s, $sim_ref ) = @_; + my ( $type, $name ); + + $s =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//g; - $s =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//g ; #print "instance $s\n" ; - ($type , $name) = $s =~ /([A-Za-z_]+[\w_:\*]*(?:<[^>]+>)?)\s+([A-Za-z_]+[\w_]*)/s ; + ( $type, $name ) = $s =~ /([A-Za-z_]+[\w_:\*]*(?:<[^>]+>)?)\s+([A-Za-z_]+[\w_]*)/s; + #print "instance type = $type , name = $name\n" ; - push @{$$sim_ref{instances}} , $name ; - $$sim_ref{instances_type}{$name} = $type ; + push @{ $$sim_ref{instances} }, $name; + $$sim_ref{instances_type}{$name} = $type; - $$sim_ref{instance_declarations} .= "$s\n" ; + $$sim_ref{instance_declarations} .= "$s\n"; - trick_print($$sim_ref{fh},"Instantiation: $s\n", "debug_white", $$sim_ref{args}{v}) ; + trick_print( $$sim_ref{fh}, "Instantiation: $s\n", "debug_white", $$sim_ref{args}{v} ); # remove constructor parameters - $s =~ s/\(.*/;/s ; + $s =~ s/\(.*/;/s; - if ($type =~ /<[^>]+>/) { - $$sim_ref{template_instance_declarations} .= "$s\n" ; + if ( $type =~ /<[^>]+>/ ) { + $$sim_ref{template_instance_declarations} .= "$s\n"; } - $$sim_ref{extern_instance_declarations} .= "extern $s\n" ; + $$sim_ref{extern_instance_declarations} .= "extern $s\n"; } sub handle_create_connections($$$) { - my ($s, $file_contents, $sim_ref) = @_; - my ($cc_code) ; + my ( $s, $file_contents, $sim_ref ) = @_; + my ($cc_code); - ($cc_code, $$file_contents) = extract_bracketed($$file_contents,"{}"); + ( $cc_code, $$file_contents ) = extract_bracketed( $$file_contents, "{}" ); - trick_print($$sim_ref{fh},"Create connections code: $cc_code\n", "debug_white", $$sim_ref{args}{v}) ; + trick_print( $$sim_ref{fh}, "Create connections code: $cc_code\n", "debug_white", $$sim_ref{args}{v} ); - $cc_code =~ s/^{//s ; - $cc_code =~ s/}$//s ; - $cc_code =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//g ; + $cc_code =~ s/^{//s; + $cc_code =~ s/}$//s; + $cc_code =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//g; + + $$sim_ref{create_connections} .= $cc_code; - $$sim_ref{create_connections} .= $cc_code ; #print $$sim_ref{create_connections} ; } sub handle_line_tag($$) { - my ($s, $sim_ref) = @_; - my ($line_num , $file_name) = $s =~ /(\d+)\s*\"(.*?)\"/; - trick_print($$sim_ref{fh},"Line: $s\n", "debug_yellow", $$sim_ref{args}{v}) ; + my ( $s, $sim_ref ) = @_; + my ( $line_num, $file_name ) = $s =~ /(\d+)\s*\"(.*?)\"/; + trick_print( $$sim_ref{fh}, "Line: $s\n", "debug_yellow", $$sim_ref{args}{v} ); if ( $file_name !~ /^\ ; - %header = extract_trick_header( $file_name, $file_contents, 0 , 0 ); + my %header; + local $/ = undef; + open TEXT, '<', $file_name; + my $file_contents = ; + %header = extract_trick_header( $file_name, $file_contents, 0, 0 ); + # set the language if an override in the header is found if ( $header{language} eq "CPP" ) { - $suffix = "cpp" ; + $suffix = "cpp"; } else { - $suffix = "c" ; + $suffix = "c"; } - } else { - $suffix = "cpp" ; } + else { + $suffix = "cpp"; + } + # save off suffix for make_makefile - $$sim_ref{headers_lang}{$file_name} = $suffix ; + $$sim_ref{headers_lang}{$file_name} = $suffix; - } else { - trick_print($$sim_ref{fh},"ERROR: S_define:$$sim_ref{line_num}: ##include expects \"FILENAME\" (double quotes for FILENAME) \n", "title_red", $$sim_ref{args}{v}) ; + } + else { + trick_print( $$sim_ref{fh}, + "ERROR: S_define:$$sim_ref{line_num}: ##include expects \"FILENAME\" (double quotes for FILENAME) \n", + "title_red", $$sim_ref{args}{v} ); } } } sub preparse_job_class_order($$) { - my ( $job_class_order_structs , $sim_ref ) = @_ ; - my $class_text ; - my @class_list ; - my %temp_hash ; + my ( $job_class_order_structs, $sim_ref ) = @_; + my $class_text; + my @class_list; + my %temp_hash; if ( scalar @{$job_class_order_structs} > 1 ) { - edit_and_exit("Multiple job order constructs found" , "$s_define_file" , 1 ) ; - } elsif ( scalar @{$job_class_order_structs} == 0 ) { - return ; + edit_and_exit( "Multiple job order constructs found", "$s_define_file", 1 ); + } + elsif ( scalar @{$job_class_order_structs} == 0 ) { + return; } # get a list of classes - ($class_text) = @{$job_class_order_structs}[0] =~ /{(.*?)}/sx ; - $class_text =~ s/^\s+|\s+$//gs ; - @class_list = split /\s*,\s*/ , $class_text ; + ($class_text) = @{$job_class_order_structs}[0] =~ /{(.*?)}/sx; + $class_text =~ s/^\s+|\s+$//gs; + @class_list = split /\s*,\s*/, $class_text; # check to make sure the class names are not duplicated - foreach my $c ( @class_list ) { + foreach my $c (@class_list) { if ( exists $temp_hash{$c} ) { - trick_print($$sim_ref{fh}, "\nCP ERROR:\n Job class \"$c\" duplicated in new order.\n" , "title_red" , $$sim_ref{args}{v} ) ; - edit_and_exit("CP bad job class order" , "$s_define_file" , 1 ) ; + trick_print( $$sim_ref{fh}, "\nCP ERROR:\n Job class \"$c\" duplicated in new order.\n", + "title_red", $$sim_ref{args}{v} ); + edit_and_exit( "CP bad job class order", "$s_define_file", 1 ); } - $temp_hash{$c}++ ; + $temp_hash{$c}++; } # save the new order - @{$$sim_ref{user_class_order}} = @class_list ; + @{ $$sim_ref{user_class_order} } = @class_list; # push on classes important to trick system function if not specified if ( !exists $temp_hash{automatic} ) { - unshift @{$$sim_ref{user_class_order}} , "automatic" ; + unshift @{ $$sim_ref{user_class_order} }, "automatic"; } if ( !exists $temp_hash{automatic_last} ) { - push @{$$sim_ref{user_class_order}} , "automatic_last" ; + push @{ $$sim_ref{user_class_order} }, "automatic_last"; } if ( !exists $temp_hash{logging} ) { - push @{$$sim_ref{user_class_order}} , "logging" ; + push @{ $$sim_ref{user_class_order} }, "logging"; } if ( !exists $temp_hash{data_record} ) { - push @{$$sim_ref{user_class_order}} , "data_record" ; + push @{ $$sim_ref{user_class_order} }, "data_record"; } if ( !exists $temp_hash{system_checkpoint} ) { - push @{$$sim_ref{user_class_order}} , "system_checkpoint" ; + push @{ $$sim_ref{user_class_order} }, "system_checkpoint"; } if ( !exists $temp_hash{system_advance_sim_time} ) { - push @{$$sim_ref{user_class_order}} , "system_advance_sim_time" ; + push @{ $$sim_ref{user_class_order} }, "system_advance_sim_time"; } if ( !exists $temp_hash{system_moding} ) { - push @{$$sim_ref{user_class_order}} , "system_moding" ; + push @{ $$sim_ref{user_class_order} }, "system_moding"; } if ( !exists $temp_hash{integ_loop} ) { - push @{$$sim_ref{user_class_order}} , "integ_loop" ; + push @{ $$sim_ref{user_class_order} }, "integ_loop"; } } diff --git a/libexec/trick/pm/s_source.pm b/libexec/trick/pm/s_source.pm index efdc25c14..f68866a29 100644 --- a/libexec/trick/pm/s_source.pm +++ b/libexec/trick/pm/s_source.pm @@ -1,38 +1,40 @@ -package s_source ; +package s_source; use Exporter (); -@ISA = qw(Exporter); +@ISA = qw(Exporter); @EXPORT = qw(s_source); -use strict ; -use gte ; -use trick_version ; +use strict; +use gte; +use trick_version; sub s_source($) { - my ($sim_ref) = @_ ; - my (@cpp_headers , @c_headers) ; + my ($sim_ref) = @_; + my ( @cpp_headers, @c_headers ); #-------------------------------------------------------------- # Generate S_source.c - open S_SOURCE, ">build/S_source.cpp" or die "Couldn't open build/S_source.cpp!\n"; - open S_SOURCE_H, ">S_source.hh" or die "Couldn't open S_source.hh!\n"; - open TOP_LEVEL_OBJECTS_RESOURCE, ">build/top_level_objects.resource" or die "Couldn't open top_level_objects.resource!"; + open S_SOURCE, ">$ENV{'TRICK_BUILD_DIR'}build/S_source.cpp" + or die "Couldn't open $ENV{'TRICK_BUILD_DIR'}build/S_source.cpp!\n"; + open S_SOURCE_H, ">$ENV{'TRICK_BUILD_DIR'}S_source.hh" or die "Couldn't open $ENV{'TRICK_BUILD_DIR'}S_source.hh!\n"; + open TOP_LEVEL_OBJECTS_RESOURCE, ">$ENV{'TRICK_BUILD_DIR'}build/top_level_objects.resource" + or die "Couldn't open $ENV{'TRICK_BUILD_DIR'}top_level_objects.resource!"; + # Get Trick version - my ($version, $thread) = get_trick_version() ; + my ( $version, $thread ) = get_trick_version(); #--------------------------- # Get date - my $date = localtime ; - my ($sec,$min,$hour,$mday,$mon,$year) = localtime ; - $year += 1900 ; - $mon += 1 ; - my ($login) = getpwuid($<) ; + my $date = localtime; + my ( $sec, $min, $hour, $mday, $mon, $year ) = localtime; + $year += 1900; + $mon += 1; + my ($login) = getpwuid($<); #--------------------------- # Print version - date - printf S_SOURCE "\n/* Created $year/%02d/%02d %02d\:%02d\:%02d $login \$ */\n", - $mon , $mday , $hour , $min , $sec ; + printf S_SOURCE "\n/* Created $year/%02d/%02d %02d\:%02d\:%02d $login \$ */\n", $mon, $mday, $hour, $min, $sec; #--------------------------- # Includes @@ -56,44 +58,46 @@ PURPOSE: #include \"trick/SimObject.hh\" #include \"trick/JobData.hh\" -#include \"trick/UnitsMap.hh\"\n\n" ; +#include \"trick/UnitsMap.hh\"\n\n"; # TODO get rid of this statement! This is still here because of the collect - print S_SOURCE_H "#define ip_alloc calloc\n" ; - print S_SOURCE_H "$$sim_ref{system_headers}\n" ; + print S_SOURCE_H "#define ip_alloc calloc\n"; + print S_SOURCE_H "$$sim_ref{system_headers}\n"; - foreach my $h ( @{$$sim_ref{sim_class_includes}} ) { + foreach my $h ( @{ $$sim_ref{sim_class_includes} } ) { if ( $h !~ /\.h$/ ) { - push @cpp_headers , $h ; + push @cpp_headers, $h; } else { - my ($full_path) ; - $full_path = $$sim_ref{headers_full_path}{$h} ; - if ($$sim_ref{headers_lang}{$h} eq "cpp" ) { - push @cpp_headers , $h ; + my ($full_path); + $full_path = $$sim_ref{headers_full_path}{$h}; + if ( $$sim_ref{headers_lang}{$h} eq "cpp" ) { + push @cpp_headers, $h; } else { - push @c_headers , $h ; + push @c_headers, $h; } } } - my %temp_hash ; - @cpp_headers = grep ++$temp_hash{$_} < 2, @cpp_headers ; + my %temp_hash; + @cpp_headers = grep ++$temp_hash{$_} < 2, @cpp_headers; foreach my $h ( sort @cpp_headers ) { - my $printed = 0 ; + my $printed = 0; + # list header files that are not under the trick_source directory # (e.g. trick_models/ directory) if ( $h !~ s/^TRICK_HOME\/trick_source\/// ) { - foreach ( @{$$sim_ref{inc_paths}} ) { - if ($h =~ s,^$_/,, ) { + foreach ( @{ $$sim_ref{inc_paths} } ) { + if ( $h =~ s,^$_/,, ) { print S_SOURCE_H "#include \"$h\"\n"; - $printed = 1 ; - last ; + $printed = 1; + last; } } } + # list header files that are in trick_source if ( $printed eq 0 ) { print S_SOURCE_H "#include \"$h\"\n"; @@ -101,18 +105,16 @@ PURPOSE: } if ( scalar @c_headers ) { - print S_SOURCE_H "\n#ifdef __cplusplus\n" , - "extern \"C\" {\n" , - "#endif\n\n" ; + print S_SOURCE_H "\n#ifdef __cplusplus\n", "extern \"C\" {\n", "#endif\n\n"; foreach my $h ( sort @c_headers ) { - my $printed = 0 ; + my $printed = 0; if ( $h !~ s/^TRICK_HOME\/trick_source\/// ) { - foreach ( @{$$sim_ref{inc_paths}} ) { - if ($h =~ s,^$_/,, ) { + foreach ( @{ $$sim_ref{inc_paths} } ) { + if ( $h =~ s,^$_/,, ) { print S_SOURCE_H "#include \"$h\"\n"; - $printed = 1 ; - last ; + $printed = 1; + last; } } } @@ -121,119 +123,117 @@ PURPOSE: } } - print S_SOURCE_H "\n#ifdef __cplusplus\n" , - "}\n" , - "#endif\n" ; + print S_SOURCE_H "\n#ifdef __cplusplus\n", "}\n", "#endif\n"; } - print S_SOURCE_H "\n" ; + print S_SOURCE_H "\n"; # prints the user defined header code - print S_SOURCE_H "$$sim_ref{user_header}\n" ; + print S_SOURCE_H "$$sim_ref{user_header}\n"; # prints classes defined in S_define file. Set in parse_s_define.pm - print S_SOURCE_H $$sim_ref{sim_class_code} ; + print S_SOURCE_H $$sim_ref{sim_class_code}; # prints an instantiation for each templated sim object for ICG to process. - print S_SOURCE_H "#ifdef TRICK_ICG\n" ; - print S_SOURCE_H $$sim_ref{template_instance_declarations} ; - print S_SOURCE_H "#endif\n\n" ; + print S_SOURCE_H "#ifdef TRICK_ICG\n"; + print S_SOURCE_H $$sim_ref{template_instance_declarations}; + print S_SOURCE_H "#endif\n\n"; # prints an extern declaration for each sim object - print S_SOURCE_H "#ifndef SWIG\n" ; - print S_SOURCE_H $$sim_ref{extern_instance_declarations} ; - print S_SOURCE_H "#endif\n" ; + print S_SOURCE_H "#ifndef SWIG\n"; + print S_SOURCE_H $$sim_ref{extern_instance_declarations}; + print S_SOURCE_H "#endif\n"; - print S_SOURCE_H "\n\n#endif\n" ; + print S_SOURCE_H "\n\n#endif\n"; - close S_SOURCE_H ; + close S_SOURCE_H; - print S_SOURCE "#include \"../S_source.hh\"\n" ; + print S_SOURCE "#include \"../S_source.hh\"\n"; - print S_SOURCE "$$sim_ref{user_code}\n" ; + print S_SOURCE "$$sim_ref{user_code}\n"; # prints associated call functions - print S_SOURCE $$sim_ref{sim_class_call_functions} ; + print S_SOURCE $$sim_ref{sim_class_call_functions}; # prints instantiations from S_define file. Set in parse_s_define.pm - print S_SOURCE "\n// Instantiate stuff\n" ; - print S_SOURCE $$sim_ref{instance_declarations} ; + print S_SOURCE "\n// Instantiate stuff\n"; + print S_SOURCE $$sim_ref{instance_declarations}; # prints integration loop sim objects from S_define file - print S_SOURCE "\n// Integration Loop Sim Object(s) JMP\n" ; - foreach my $integ_loop ( @{$$sim_ref{integ_loop}} ) { - print S_SOURCE "IntegLoopSimObject $$integ_loop{name}($$integ_loop{cycle}, $$integ_loop{child}" ; - my @integ_loop_sim_objects = split(/\s*,\s*/, $$integ_loop{name_list} ) ; + print S_SOURCE "\n// Integration Loop Sim Object(s) JMP\n"; + foreach my $integ_loop ( @{ $$sim_ref{integ_loop} } ) { + print S_SOURCE "IntegLoopSimObject $$integ_loop{name}($$integ_loop{cycle}, $$integ_loop{child}"; + my @integ_loop_sim_objects = split( /\s*,\s*/, $$integ_loop{name_list} ); foreach my $integ_loop_sim_obj (@integ_loop_sim_objects) { - print S_SOURCE ", &$integ_loop_sim_obj" ; + print S_SOURCE ", &$integ_loop_sim_obj"; } - print S_SOURCE ", (void *)NULL);\n" ; + print S_SOURCE ", (void *)NULL);\n"; } #--------------------------- # Default Environment - print S_SOURCE "\n/* Default Environment */\n" , - "SimEnvironment::SimEnvironment() {\n\n" ; + print S_SOURCE "\n/* Default Environment */\n", "SimEnvironment::SimEnvironment() {\n\n"; print S_SOURCE gte("S_source"); - print S_SOURCE "}\n\n" ; - + print S_SOURCE "}\n\n"; #--------------------------- # Memory Init - print S_SOURCE "Trick::ClassSizeCheck * Trick::ClassSizeCheck::pInstance = NULL ;\n" ; + print S_SOURCE "Trick::ClassSizeCheck * Trick::ClassSizeCheck::pInstance = NULL ;\n"; - print S_SOURCE "\n/* Memory Init */\n" , - "void memory_init( void ) {\n\n" ; + print S_SOURCE "\n/* Memory Init */\n", "void memory_init( void ) {\n\n"; - print S_SOURCE " " x 4 , "ALLOC_INFO * ai ;\n" ; - print S_SOURCE " " x 4 , "exec_set_version_date_tag\( \"@(#)CP Version $version, $date\" \) ;\n" ; - print S_SOURCE " " x 4 , "exec_set_build_date\( \"$date\" \) ;\n" ; - print S_SOURCE " " x 4 , "exec_set_current_version\( \"$version\" \) ;\n\n" ; + print S_SOURCE " " x 4, "ALLOC_INFO * ai ;\n"; + print S_SOURCE " " x 4, "exec_set_version_date_tag\( \"@(#)CP Version $version, $date\" \) ;\n"; + print S_SOURCE " " x 4, "exec_set_build_date\( \"$date\" \) ;\n"; + print S_SOURCE " " x 4, "exec_set_current_version\( \"$version\" \) ;\n\n"; - print S_SOURCE " " x 4 , "populate_sim_services_class_map\(\) ;\n" ; - print S_SOURCE " " x 4 , "populate_sim_services_enum_map\(\) ;\n" ; - print S_SOURCE " " x 4 , "populate_class_map\(\) ;\n" ; - print S_SOURCE " " x 4 , "populate_enum_map\(\) ;\n" ; - print S_SOURCE "\n" ; + print S_SOURCE " " x 4, "populate_sim_services_class_map\(\) ;\n"; + print S_SOURCE " " x 4, "populate_sim_services_enum_map\(\) ;\n"; + print S_SOURCE " " x 4, "populate_class_map\(\) ;\n"; + print S_SOURCE " " x 4, "populate_enum_map\(\) ;\n"; + print S_SOURCE "\n"; # prints the job class order for the cyclic jobs - foreach my $cl ( @{$$sim_ref{user_class_order}} ) { - print S_SOURCE" exec_add_scheduled_job_class(\"$cl\") ;\n" ; + foreach my $cl ( @{ $$sim_ref{user_class_order} } ) { + print S_SOURCE" exec_add_scheduled_job_class(\"$cl\") ;\n"; } - print S_SOURCE "\n" ; - - foreach my $inst ( @{$$sim_ref{instances}} ) { - print S_SOURCE " " x 4 , "exec_add_sim_object(&$inst, \"$inst\") ;\n" ; - my $temp_type = $$sim_ref{instances_type}{$inst} ; - $temp_type =~ s/\s//g ; - $temp_type =~ s/[<>,:*]/_/g ; - print S_SOURCE " " x 4 , "TMM_declare_ext_var(&$inst, TRICK_STRUCTURED,\"$temp_type\", 0, \"$inst\", 0, NULL) ;\n" ; - print S_SOURCE " " x 4 , "if ( (ai = get_alloc_info_at(&$inst)) != NULL ) {\n" ; - print S_SOURCE " " x 8 , "ai->alloced_in_memory_init = 1 ;\n" ; - print S_SOURCE " " x 4 , "}\n" ; - print TOP_LEVEL_OBJECTS_RESOURCE " \\n \\n\n"; + print S_SOURCE "\n"; + + foreach my $inst ( @{ $$sim_ref{instances} } ) { + print S_SOURCE " " x 4, "exec_add_sim_object(&$inst, \"$inst\") ;\n"; + my $temp_type = $$sim_ref{instances_type}{$inst}; + $temp_type =~ s/\s//g; + $temp_type =~ s/[<>,:*]/_/g; + print S_SOURCE " " x 4, + "TMM_declare_ext_var(&$inst, TRICK_STRUCTURED,\"$temp_type\", 0, \"$inst\", 0, NULL) ;\n"; + print S_SOURCE " " x 4, "if ( (ai = get_alloc_info_at(&$inst)) != NULL ) {\n"; + print S_SOURCE " " x 8, "ai->alloced_in_memory_init = 1 ;\n"; + print S_SOURCE " " x 4, "}\n"; + print TOP_LEVEL_OBJECTS_RESOURCE + " \\n \\n\n"; } - - print S_SOURCE " " x 4 , "// Add Integration Loop Sim Object(s) JMP\n" ; - foreach my $integ_loop ( sort sim_integ_by_name @{$$sim_ref{integ_loop}} ) { - print S_SOURCE " " x 4 , "exec_add_sim_object(&$$integ_loop{name} , \"$$integ_loop{name}\") ;\n" ; - print S_SOURCE " " x 4 , "TMM_declare_ext_var(&$$integ_loop{name}, TRICK_STRUCTURED,\"IntegLoopSimObject\", 0, \"$$integ_loop{name}\", 0, NULL) ;\n" ; - print S_SOURCE " " x 4 , "if ( (ai = get_alloc_info_at(&$$integ_loop{name})) != NULL ) {\n" ; - print S_SOURCE " " x 8 , "ai->alloced_in_memory_init = 1 ;\n" ; - print S_SOURCE " " x 4 , "}\n" ; - print TOP_LEVEL_OBJECTS_RESOURCE " \\n \\n\n"; + print S_SOURCE " " x 4, "// Add Integration Loop Sim Object(s) JMP\n"; + foreach my $integ_loop ( sort sim_integ_by_name @{ $$sim_ref{integ_loop} } ) { + print S_SOURCE " " x 4, "exec_add_sim_object(&$$integ_loop{name} , \"$$integ_loop{name}\") ;\n"; + print S_SOURCE " " x 4, + "TMM_declare_ext_var(&$$integ_loop{name}, TRICK_STRUCTURED,\"IntegLoopSimObject\", 0, \"$$integ_loop{name}\", 0, NULL) ;\n"; + print S_SOURCE " " x 4, "if ( (ai = get_alloc_info_at(&$$integ_loop{name})) != NULL ) {\n"; + print S_SOURCE " " x 8, "ai->alloced_in_memory_init = 1 ;\n"; + print S_SOURCE " " x 4, "}\n"; + print TOP_LEVEL_OBJECTS_RESOURCE + " \\n \\n\n"; } - close TOP_LEVEL_OBJECTS_RESOURCE ; - print S_SOURCE "\n" ; + close TOP_LEVEL_OBJECTS_RESOURCE; + print S_SOURCE "\n"; - print S_SOURCE $$sim_ref{create_connections} ; + print S_SOURCE $$sim_ref{create_connections}; - print S_SOURCE "\n" , - " " x 4 , "Trick::ClassSizeCheck::class_size_check()->print_nonzero_diffs() ;\n" , - " " x 4 , "Trick::ClassSizeCheck::reset_instance() ;\n" , - " " x 4 , "return ;\n" , - "}\n\n" ; + print S_SOURCE "\n", + " " x 4, "Trick::ClassSizeCheck::class_size_check()->print_nonzero_diffs() ;\n", + " " x 4, "Trick::ClassSizeCheck::reset_instance() ;\n", + " " x 4, "return ;\n", + "}\n\n"; #------------------------------------------ # Write out the 'exec_collect_init()' function in S_source.c @@ -262,80 +262,81 @@ PURPOSE: #------------- # Write the exec_collect_init() entry point. - print S_SOURCE "\n/*---------------------------------------------------------------------*/\n\n" ; + print S_SOURCE "\n/*---------------------------------------------------------------------*/\n\n"; - print S_SOURCE "void exec_collect_init( void ) {\n\n" ; + print S_SOURCE "void exec_collect_init( void ) {\n\n"; if ( exists $$sim_ref{collect} ) { -# print S_SOURCE " " x 4 , "long * lp ;\n\n" ; -# -# -# foreach my $collect ( sort sim_collect_by_name @{$$sim_ref{collect}} ) { -# # Number of params in collect statement -# my $np = $$collect{num_params} ; -# -# print S_SOURCE " " x 4 , "$$collect{name} = (void**)ip_alloc( $np + 1 , sizeof(void*));\n" , -# " " x 4 , "lp = (long *)$$collect{name} ;\n" , -# " " x 4 , "*lp = $np ;\n" , -# " " x 4 , "$$collect{name}++ ;\n" ; -# -# for ( my $i = 0; $i < $np ; $i++ ) { -# my $name = @{$$collect{params}}[$i] ; -# print S_SOURCE " " x 4 , "$$collect{name}\[$i\] = (void*)&($name);\n" ; -# } -# } + # print S_SOURCE " " x 4 , "long * lp ;\n\n" ; + # + # + # foreach my $collect ( sort sim_collect_by_name @{$$sim_ref{collect}} ) { + # # Number of params in collect statement + # my $np = $$collect{num_params} ; + # + # print S_SOURCE " " x 4 , "$$collect{name} = (void**)ip_alloc( $np + 1 , sizeof(void*));\n" , + # " " x 4 , "lp = (long *)$$collect{name} ;\n" , + # " " x 4 , "*lp = $np ;\n" , + # " " x 4 , "$$collect{name}++ ;\n" ; + # + # for ( my $i = 0; $i < $np ; $i++ ) { + # my $name = @{$$collect{params}}[$i] ; + # print S_SOURCE " " x 4 , "$$collect{name}\[$i\] = (void*)&($name);\n" ; + # } + # } #print S_SOURCE "\n#if 0\n" ; - foreach my $collect ( @{$$sim_ref{collect}} ) { - print S_SOURCE " " x 4 , "$$collect{name} = NULL ;\n" ; - my $np = $$collect{num_params} ; - foreach my $name ( @{$$collect{params}} ) { - print S_SOURCE " " x 4 , "$$collect{name} = add_collect($$collect{name}, (void*)&($name));\n" ; + foreach my $collect ( @{ $$sim_ref{collect} } ) { + print S_SOURCE " " x 4, "$$collect{name} = NULL ;\n"; + my $np = $$collect{num_params}; + foreach my $name ( @{ $$collect{params} } ) { + print S_SOURCE " " x 4, "$$collect{name} = add_collect($$collect{name}, (void*)&($name));\n"; } } + #print S_SOURCE "\n#endif\n" ; } if ( exists $$sim_ref{vcollect} ) { - foreach my $collect ( sort sim_vcollect_by_name @{$$sim_ref{vcollect}} ) { + foreach my $collect ( sort sim_vcollect_by_name @{ $$sim_ref{vcollect} } ) { - my $name = $$collect{name} ; - my $func = $$collect{constructor} ; - undef $func if ( defined $func ) && ( $func eq "" ) ; - foreach my $item ( sort @{$$collect{items}} ) { - my $ref = $item ; + my $name = $$collect{name}; + my $func = $$collect{constructor}; + undef $func if ( defined $func ) && ( $func eq "" ); + foreach my $item ( sort @{ $$collect{items} } ) { + my $ref = $item; if ( $ref =~ s/&// ) { - $ref = "&($ref)" ; - } else { - $ref = "$ref" ; + $ref = "&($ref)"; + } + else { + $ref = "$ref"; } - if (defined $func ) { - $ref = "$func( $ref )" ; + if ( defined $func ) { + $ref = "$func( $ref )"; } - print S_SOURCE " " x 4, "$name.push_back(\n", " " x 24, "$ref );\n" ; + print S_SOURCE " " x 4, "$name.push_back(\n", " " x 24, "$ref );\n"; } - print S_SOURCE "\n" ; + print S_SOURCE "\n"; } } - print S_SOURCE " " x 4, "return ;\n" , - "}\n\n" ; + print S_SOURCE " " x 4, "return ;\n", "}\n\n"; - print S_SOURCE "int master( int nargs, char ** args ) ;\n\n" ; - print S_SOURCE "int main( int nargs, char ** args ) {\n" ; - print S_SOURCE " " x 4 , "return master(nargs, args) ;\n" ; - print S_SOURCE "}\n" ; + print S_SOURCE "int master( int nargs, char ** args ) ;\n\n"; + print S_SOURCE "int main( int nargs, char ** args ) {\n"; + print S_SOURCE " " x 4, "return master(nargs, args) ;\n"; + print S_SOURCE "}\n"; - close S_SOURCE ; + close S_SOURCE; - - open S_INSTANCE, ">build/CP_instances" or die "Couldn't open build/CP_instances!\n"; - print S_INSTANCE $$sim_ref{extern_instance_declarations} ; - foreach my $integ_loop ( @{$$sim_ref{integ_loop}} ) { - print S_INSTANCE "extern IntegLoopSimObject $$integ_loop{name} ;\n" ; + open S_INSTANCE, ">$ENV{TRICK_BUILD_DIR}build/CP_instances" + or die "Couldn't open $ENV{TRICK_BUILD_DIR}build/CP_instances!\n"; + print S_INSTANCE $$sim_ref{extern_instance_declarations}; + foreach my $integ_loop ( @{ $$sim_ref{integ_loop} } ) { + print S_INSTANCE "extern IntegLoopSimObject $$integ_loop{name} ;\n"; } - close S_INSTANCE ; + close S_INSTANCE; } #-------------------------------------------------------------- @@ -344,8 +345,10 @@ PURPOSE: sub sim_integ_by_name { return + #Sort by sim integrate name in ASCII order - ( ${$a}{name} cmp ${$b}{name} ) || + ( ${$a}{name} cmp ${$b}{name} ) || + #If two names are identical, then sort based on cycle time ( ${$a}{cycle} <=> ${$b}{cycle} ); } @@ -356,8 +359,10 @@ sub sim_integ_by_name { sub sim_collect_by_name { return + #Sort by sim collect statement name in ASCII order - ( ${$a}{name} cmp ${$b}{name} ) || + ( ${$a}{name} cmp ${$b}{name} ) || + #If two params are identical, then sort based on num_params ( ${$a}{num_params} <=> ${$b}{num_params} ); } @@ -368,6 +373,7 @@ sub sim_collect_by_name { sub sim_vcollect_by_name { return + #Sort by sim collect statement name in ASCII order ( ${$a}{name} cmp ${$b}{name} ); } diff --git a/libexec/trick/pm/swig_make.pm b/libexec/trick/pm/swig_make.pm new file mode 100644 index 000000000..446b2af77 --- /dev/null +++ b/libexec/trick/pm/swig_make.pm @@ -0,0 +1,332 @@ +package swig_make; + +use FindBin qw($RealBin); +use lib "$RealBin/"; + +use File::Basename; +use File::Path qw(make_path); +use Cwd; +use Cwd 'abs_path'; +use gte; +use html; +use verbose_build; +use get_lib_deps; +use get_paths; +use get_hashtag_includes; +use trick_print; +use Digest::MD5 qw(md5_hex); + +@ISA = qw(Exporter); +@EXPORT = + qw(read_files_to_process write_makefile_swig_deps get_trick_headers purge_swig_no_files write_makefile_swig write_lib_files); + +use strict; + +my @files_to_process; +my @ext_lib_files; +my %md5s; +my $verbose_build = verbose_build(); +my %trick_headers; +my %python_modules; +my %python_module_dirs; + +#trickify vars +my %trickify_files_to_replace; +my %trickify_gcc_includes; + +sub read_files_to_process() { + my ( $files_to_process, $ext_lib_files, $md5s ) = get_s_source_deps(); + @files_to_process = @$files_to_process; + @ext_lib_files = @$ext_lib_files; + %md5s = %$md5s; +} + +sub write_makefile_swig_deps() { + open DEPENDENCIES_FILE, ">$ENV{TRICK_BUILD_DIR}build/Makefile_swig_deps" + or die "Could not open $ENV{TRICK_BUILD_DIR}build/Makefile_swig_deps for writing"; + print DEPENDENCIES_FILE "$ENV{TRICK_BUILD_DIR}build/Makefile_swig:"; + foreach my $file ( @files_to_process, @ext_lib_files ) { + print DEPENDENCIES_FILE " \\\n " . $file; + } + close DEPENDENCIES_FILE; +} + +sub get_trick_headers() { + foreach my $f ( @files_to_process, @ext_lib_files ) { + my %trick_header = extract_trick_header( $f, do { local ( @ARGV, $/ ) = $f; <> }, 0, 0 ); + if ( exists $trick_header{python_module} ) { + $trick_headers{$f}{python_module} = $trick_header{python_module}; + ( $trick_headers{$f}{python_module_dir} = $trick_header{python_module} ) =~ s/\./\//g; + $python_modules{ $trick_headers{$f}{python_module} } = 1; + $python_module_dirs{ $trick_headers{$f}{python_module_dir} } = 1; + } + } +} + +sub has_swig_no { + my $result = $trick_headers{ $_[0] }{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 $s_source_md5 = md5_hex( abs_path("$ENV{TRICK_BUILD_DIR}S_source.hh") ); + my $swig_sim_dir = "$ENV{'TRICK_BUILD_DIR'}.trick"; + my $swig_sim_zip = "trick.zip"; + my $swig_src_dir = "$ENV{'TRICK_BUILD_DIR'}build"; + + open MAKEFILE, ">$ENV{TRICK_BUILD_DIR}build/Makefile_swig" + or die "Could not open $ENV{TRICK_BUILD_DIR}build/Makefile_swig for writing"; + print MAKEFILE + "TRICK_SYSTEM_SWIG_CFLAGS := -I../include \${PYTHON_INCLUDES} -Wno-shadow -Wno-missing-field-initializers + +ifeq (\$(IS_CC_CLANG), 1) + TRICK_SYSTEM_SWIG_CFLAGS += -Wno-self-assign -Wno-sometimes-uninitialized -Wno-deprecated-register -Wno-unused-variable -Wno-unused-but-set-variable -Wno-cast-function-type-mismatch +else + TRICK_SYSTEM_SWIG_CFLAGS += -Wno-unused-but-set-variable -Wno-maybe-uninitialized + ifeq (\$(shell test \$(GCC_MAJOR) -ge 8; echo \$\$?), 0) + TRICK_SYSTEM_SWIG_CFLAGS += -Wno-cast-function-type + endif +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\$(call ECHO_AND_LOG,/bin/cp -f \$< \$@) + +# SWIG_I ======================================================================= + +SWIG_I ="; + + foreach my $file (@files_to_process) { + ( my $swig_file = $file ) =~ s/(\.[^.]*)?$/_py/; + print MAKEFILE " \\\n $ENV{TRICK_BUILD_DIR}build$swig_file.i"; + } + + print MAKEFILE " + +define create_convert_swig_rule +$ENV{TRICK_BUILD_DIR}build/%_py.i: /%.\$1 +\t\$\$(call ECHO_AND_LOG,\${TRICK_HOME}/\$(LIBEXEC)/trick/convert_swig \$\${TRICK_CONVERT_SWIG_FLAGS} \$\$<) +endef + +\$(foreach EXTENSION,H h hh hxx h++ hpp,\$(eval \$(call create_convert_swig_rule,\$(EXTENSION)))) + +$ENV{TRICK_BUILD_DIR}build/top.i: $ENV{TRICK_BUILD_DIR}build/CP_instances +\t\$(call ECHO_AND_LOG,\${PYTHON} \${TRICK_HOME}/\${LIBEXEC}/trick/create_top_dot_i) + +# SWIG_SRC ===================================================================== + +SWIG_SRC = \$(subst .i,.cpp,\$(SWIG_I)) ${swig_src_dir}/top.cpp + +\$(SWIG_SRC) : %.cpp: %.i | %.d \$(SWIG_I) +\t\$(PRINT_SWIG) +\t\$(call ECHO_AND_LOG,\$(SWIG) \$(TRICK_INCLUDE) \$(TRICK_DEFINES) \$(TRICK_VERSIONS) \$(TRICK_SWIG_FLAGS) -c++ -python -includeall -ignoremissing -w201 -w303 -w315 -w325 -w362 -w389 -w401 -w451 -MMD -MP -outdir $swig_sim_dir -o \$@ \$<) + +\$(SWIG_SRC:.cpp=.d): ; + +-include \$(SWIG_SRC:.cpp=.d) + +# 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\$(call ECHO_AND_LOG,\$(TRICK_CXX) \$(TRICK_CXXFLAGS) \$(TRICK_SYSTEM_CXXFLAGS) \$(TRICK_SWIG_CFLAGS) \$(TRICK_SYSTEM_SWIG_CFLAGS) -Wno-unused-parameter -c -o \$@ \$<) + +\$(S_MAIN): \$(SWIG_OBJECTS) + +LINK_LISTS += \$(LD_FILELIST)$ENV{TRICK_BUILD_DIR}build/py_link_list + +# $ENV{'TRICK_BUILD_DIR'}$swig_sim_zip =================================================================== + +$ENV{'TRICK_BUILD_DIR'}$swig_sim_zip: \$(SWIG_SRC) \$(TRICK_FIXED_PYTHON) $swig_sim_dir/__init__.py +\t\$(info \$(call COLOR,Compiling) Python modules) +\t\$(call ECHO_AND_LOG,\$(PYTHON) -m compileall -q $swig_sim_dir) +\t\$(info \$(call COLOR,Zipping) Python modules into \$@) +\t\$(call ECHO_AND_LOG,ln -sf $swig_sim_dir trick) +\t\$(call ECHO_AND_LOG,zip -rq $ENV{'TRICK_BUILD_DIR'}$swig_sim_zip trick) +\t\$(call ECHO_AND_LOG,rm -f trick) + + +all: $ENV{'TRICK_BUILD_DIR'}$swig_sim_zip +"; + + open INITSWIGFILE, ">$ENV{TRICK_BUILD_DIR}build/init_swig_modules.cpp" + or die "Could not open $ENV{TRICK_BUILD_DIR}build/init_swig_modules.cpp for writing"; + print INITSWIGFILE "#include \n"; + print INITSWIGFILE "#if PY_VERSION_HEX >= 0x03000000\n"; + print INITSWIGFILE "extern \"C\" {\n\n"; + + foreach my $file ( @files_to_process, @ext_lib_files ) { + print INITSWIGFILE "PyObject * PyInit__m$md5s{$file}(void) ; /* $file */\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 my $file ( @files_to_process, @ext_lib_files ) { + next if ( $file =~ /S_source.hh/ ); + print INITSWIGFILE " PyImport_AppendInittab(\"_m$md5s{$file}\", PyInit__m$md5s{$file}) ;\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 my $file ( @files_to_process, @ext_lib_files ) { + print INITSWIGFILE "void init_m$md5s{$file}(void) ; /* $file */\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 my $file ( @files_to_process, @ext_lib_files ) { + next if ( $file =~ /S_source.hh/ ); + print INITSWIGFILE " init_m$md5s{$file}() ;\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 $swig_sim_dir ) { + mkdir $swig_sim_dir; + } + open INITFILE, ">$swig_sim_dir/__init__.py" or die "Could not open $swig_sim_dir/__init__.py for writing"; + + 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() + \"/$swig_sim_zip/trick\")\n"; + foreach my $dir ( keys %python_module_dirs ) { + print INITFILE "sys.path.append(os.getcwd() + \"/$swig_sim_zip/trick/$dir\")\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 my $file ( @files_to_process, @ext_lib_files ) { + print INITFILE "# $file\n"; + print INITFILE "import _m$md5s{$file}\n"; + print INITFILE "combine_cvars(all_cvars, cvar)\n"; + print INITFILE "cvar = None\n\n"; + } + + foreach my $file ( @files_to_process, @ext_lib_files ) { + print INITFILE "# $file\n"; + print INITFILE "from m$md5s{$file} import *\n"; + } + + foreach my $mod ( keys %python_modules ) { + print INITFILE "import trick.$mod\n"; + } + + print INITFILE "\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 my $dir ( keys %python_module_dirs ) { + system("mkdir -p $swig_sim_dir/$dir"); + open MODULE_INITFILE, ">$swig_sim_dir/$dir/__init__.py"; + foreach my $file (@files_to_process) { + if ( exists $trick_headers{$file}{python_module_dir} and $trick_headers{$file}{python_module_dir} eq $dir ) + { + print MODULE_INITFILE "# $file\n"; + print MODULE_INITFILE "import _m$md5s{$file}\n"; + print MODULE_INITFILE "from m$md5s{$file} import *\n"; + } + } + close MODULE_INITFILE; + } + + return; +} + +sub write_lib_files() { + open PY_LINK_LIST, ">$ENV{TRICK_BUILD_DIR}build/py_link_list" + or die "Could not open $ENV{TRICK_BUILD_DIR}build/py_link_list for writing"; + open TRICKIFY_PY_LINK_LIST, ">$ENV{TRICK_BUILD_DIR}build/trickify_py_link_list" + or die "Could not open $ENV{TRICK_BUILD_DIR}build/trickify_py_link_list for writing"; + open SWIGLIB, ">$ENV{TRICK_BUILD_DIR}build/S_library_swig" + or die "Could not open $ENV{TRICK_BUILD_DIR}build/S_library_swig for writing"; + + print PY_LINK_LIST "$ENV{TRICK_BUILD_DIR}build/init_swig_modules.o\n"; + print PY_LINK_LIST "$ENV{TRICK_BUILD_DIR}build/top.o\n"; + + foreach my $file (@files_to_process) { + print SWIGLIB "$file\n"; + + ( my $swig_file = $file ) =~ s/(\.[^.]*)?$/_py/; + print PY_LINK_LIST "$ENV{TRICK_BUILD_DIR}build$swig_file.o\n"; + if ( !( $swig_file =~ /(.*)S_source_py$/ ) ) { + print TRICKIFY_PY_LINK_LIST "$ENV{TRICK_BUILD_DIR}build$swig_file.o\n"; + } + } + + close MAKEFILE; + close PY_LINK_LIST; + close TRICKIFY_PY_LINK_LIST; + close SWIGLIB; +} + +1; diff --git a/libexec/trick/pm/trick_print.pm b/libexec/trick/pm/trick_print.pm index c1e3b9c69..5aeb1afaa 100644 --- a/libexec/trick/pm/trick_print.pm +++ b/libexec/trick/pm/trick_print.pm @@ -1,60 +1,58 @@ -package trick_print ; +package trick_print; use Exporter (); -@ISA = qw(Exporter); -@EXPORT = qw(trick_print trick_formatted_print); - -use strict ; - -my %message_type = ( - "title_white" , { "color" , 00 , "level" , 1 } , - "title_red" , { "color" , 31 , "level" , 1 } , - "title_green" , { "color" , 32 , "level" , 1 } , - "title_yellow" , { "color" , 33 , "level" , 1 } , - "title_blue" , { "color" , 34 , "level" , 1 } , - "title_magenta" , { "color" , 35 , "level" , 1 } , - "title_cyan" , { "color" , 36 , "level" , 1 } , - "normal_white" , { "color" , 00 , "level" , 2 } , - "normal_red" , { "color" , 31 , "level" , 2 } , - "normal_green" , { "color" , 32 , "level" , 2 } , - "normal_yellow" , { "color" , 33 , "level" , 2 } , - "normal_blue" , { "color" , 34 , "level" , 2 } , - "normal_magenta" , { "color" , 35 , "level" , 2 } , - "normal_cyan" , { "color" , 36 , "level" , 2 } , - "debug_white" , { "color" , 00 , "level" , 3 } , - "debug_red" , { "color" , 31 , "level" , 3 } , - "debug_green" , { "color" , 32 , "level" , 3 } , - "debug_yellow" , { "color" , 33 , "level" , 3 } , - "debug_blue" , { "color" , 34 , "level" , 3 } , - "debug_magenta" , { "color" , 35 , "level" , 3 } , - "debug_cyan" , { "color" , 36 , "level" , 3 } - ) ; +@ISA = qw(Exporter); +@EXPORT = qw(printc trick_print trick_formatted_print); + +use strict; +use Term::ANSIColor; + +sub printc($$) { + my ( $color, $text ) = @_; + print color($color); + print $text; + print color('reset'); +} + +my %message_type = ( + "title_white", { "color", 00, "level", 1 }, "title_red", { "color", 31, "level", 1 }, + "title_green", { "color", 32, "level", 1 }, "title_yellow", { "color", 33, "level", 1 }, + "title_blue", { "color", 34, "level", 1 }, "title_magenta", { "color", 35, "level", 1 }, + "title_cyan", { "color", 36, "level", 1 }, "normal_white", { "color", 00, "level", 2 }, + "normal_red", { "color", 31, "level", 2 }, "normal_green", { "color", 32, "level", 2 }, + "normal_yellow", { "color", 33, "level", 2 }, "normal_blue", { "color", 34, "level", 2 }, + "normal_magenta", { "color", 35, "level", 2 }, "normal_cyan", { "color", 36, "level", 2 }, + "debug_white", { "color", 00, "level", 3 }, "debug_red", { "color", 31, "level", 3 }, + "debug_green", { "color", 32, "level", 3 }, "debug_yellow", { "color", 33, "level", 3 }, + "debug_blue", { "color", 34, "level", 3 }, "debug_magenta", { "color", 35, "level", 3 }, + "debug_cyan", { "color", 36, "level", 3 } +); sub trick_print($$$$) { - - my ($fh, $message, $mt , $verbose) = @_ ; - + + my ( $fh, $message, $mt, $verbose ) = @_; + # print at least lvl 2 messages to the file if ( defined $fh ) { - my ($temp_verbose) = $verbose ; - $temp_verbose = 2 if ($temp_verbose < 2) ; + my ($temp_verbose) = $verbose; + $temp_verbose = 2 if ( $temp_verbose < 2 ); if ( $temp_verbose >= $message_type{$mt}{level} ) { - print $fh "$message" ; + print $fh "$message"; } } # print the message to the screen if ( $verbose >= $message_type{$mt}{level} ) { - $message =~ s/(\n)?$/$1/s ; - print "[$message_type{$mt}{color}m$message" ; + $message =~ s/(\n)?$/$1/s; + print "[$message_type{$mt}{color}m$message"; } } sub trick_formatted_print { - my ($file, @strings) = @_; - for (my $i = 0; $i < @strings; ++$i) { + my ( $file, @strings ) = @_; + for ( my $i = 0 ; $i < @strings ; ++$i ) { print $strings[$i]; - if ($i % 2) { + if ( $i % 2 ) { print $file $strings[$i]; } } diff --git a/libexec/trick/sie_concat b/libexec/trick/sie_concat index afac248e7..4273a0057 100755 --- a/libexec/trick/sie_concat +++ b/libexec/trick/sie_concat @@ -1,52 +1,51 @@ #!/usr/bin/perl package sie_concat; -use File::Basename ; +use File::Basename; use FindBin qw($RealBin); -use lib "$RealBin/pm" ; -use get_paths ; +use lib "$RealBin/pm"; +use get_paths; -my @trick_python_paths = get_paths( "TRICK_PYTHON_PATH") ; +my @trick_python_paths = get_paths("TRICK_PYTHON_PATH"); -open(my $S_sie_resource, ">", "./S_sie.resource") - or die "cannot open S_sie.resource $!"; +open( my $S_sie_resource, ">", "$ENV{TRICK_BUILD_DIR}S_sie.resource" ) + or die "cannot open $ENV{TRICK_BUILD_DIR}S_sie.resource $!"; print $S_sie_resource "\n\n\n\n"; - -open(my $classes_resource, "<", "build/classes.resource") - or die "cannot open build/classes.resource"; -while(my $line = <$classes_resource>) { - print $S_sie_resource $line; +open( my $classes_resource, "<", "$ENV{TRICK_BUILD_DIR}build/classes.resource" ) + or die "cannot open $ENV{TRICK_BUILD_DIR}build/classes.resource"; +while ( my $line = <$classes_resource> ) { + print $S_sie_resource $line; } close($classes_resource); # Add trickified classes.resource if available -foreach my $path ( @trick_python_paths ) { - my $trickified_dir = dirname($path); - if (open(my $classes_resource, "<", "$trickified_dir/build/classes.resource")) { - while(my $line = <$classes_resource>) { - print $S_sie_resource $line; - } - close($classes_resource); - } +foreach my $path (@trick_python_paths) { + my $trickified_dir = dirname($path); + if ( open( my $classes_resource, "<", "$trickified_dir/build/classes.resource" ) ) { + while ( my $line = <$classes_resource> ) { + print $S_sie_resource $line; + } + close($classes_resource); + } } -open(my $top_level_objects_resource, "<", "build/top_level_objects.resource") - or die "cannot open build/top_level_objects.resource"; -while(my $line = <$top_level_objects_resource>) { - print $S_sie_resource $line; +open( my $top_level_objects_resource, "<", "$ENV{TRICK_BUILD_DIR}build/top_level_objects.resource" ) + or die "cannot open $ENV{TRICK_BUILD_DIR}build/top_level_objects.resource"; +while ( my $line = <$top_level_objects_resource> ) { + print $S_sie_resource $line; } close($top_level_objects_resource); my $sim_services_resource; -open($sim_services_resource, "<", "$ENV{TRICK_HOME}/share/trick/xml/sim_services_classes.resource") - or open($sim_services_resource, "<", "$ENV{TRICK_HOME}/temp_src/io_src/sim_services_classes.resource") - or die "cannot open sim_services_classes.resource"; +open( $sim_services_resource, "<", "$ENV{TRICK_HOME}/share/trick/xml/sim_services_classes.resource" ) + or open( $sim_services_resource, "<", "$ENV{TRICK_HOME}/temp_src/io_src/sim_services_classes.resource" ) + or die "cannot open sim_services_classes.resource"; -while(my $line = <$sim_services_resource>) { - print $S_sie_resource $line; +while ( my $line = <$sim_services_resource> ) { + print $S_sie_resource $line; } close($sim_services_resource); diff --git a/libexec/trick/trickify_ICG b/libexec/trick/trickify_ICG new file mode 100755 index 000000000..481df6a69 --- /dev/null +++ b/libexec/trick/trickify_ICG @@ -0,0 +1,103 @@ +#!/usr/bin/perl + +use FindBin qw($RealBin); +use lib "$RealBin/pm"; +use trick_print; + +use File::Path qw(make_path); +use File::Basename; +use File::Find; +use File::Copy; + +use Cwd qw(getcwd); + +use strict; + +my $og_trick_build_dir = $ENV{'TRICK_BUILD_DIR'}; +my %all_file_list; +my %all_io_file_list; +my %empty_file_list; +my %ext_lib_io_files_list; +my %icg_no_files_list; + +sub run_ICG($) { + my ($file) = @_; + print "ICGing:$file\n"; + system( + "$ENV{TRICK_HOME}/bin/trick-ICG $ENV{TRICK_CXXFLAGS} $ENV{TRICK_SYSTEM_CXXFLAGS} $ENV{TRICK_ICGFLAGS} $file"); +} + +sub ICG_print($) { + my ($path) = @_; + system( + "$ENV{TRICK_HOME}/bin/trick-ICG $ENV{TRICK_CXXFLAGS} $ENV{TRICK_SYSTEM_CXXFLAGS} $ENV{TRICK_ICGFLAGS} --printIO $path" + ); +} + +sub read_icg_artifacts() { + read_icg_processed(); + read_ext_lib_io_files(); + read_icg_no_found(); +} + +sub read_icg_processed() { + my $path = $ENV{'TRICK_BUILD_DIR'}; + my @trickify_io_link_list; + +#ICG_processed is actually split into two parts. First are the "non-empty" files, which we actually generate io files for. +#Aferwards are the "empty" files, which are files that ICG decides not generate io for, but are still needed for builds. +#These separate lists are smushed together in ICG_processed, so we have to find where the first list ends. +#trickify_io_link_list only contains the "non-empty list", so we can get a count of how long the non-empty file list is. + open IO_LL, "${path}build/trickify_io_link_list" or die "Could not open ${path}build/trickify_io_link_list"; + while () { + chomp; + push @trickify_io_link_list, $_; + } + close IO_LL; + + my $count; + open ICGP, "${path}build/ICG_processed" or die "Could not open ${path}build/ICG_processed"; + while () { + chomp; + if ( $count < @trickify_io_link_list ) { + $all_file_list{$_}++; + } + else { + $empty_file_list{$_}++; + } + $count++; + } + close ICGP; +} + +sub read_ext_lib_io_files() { + my $path = $ENV{'TRICK_BUILD_DIR'}; + open EXT_LIB, "${path}build/ICG_ext_lib" or die "Could not open ${path}build/ICG_ext_lib"; + while () { + chomp; + $ext_lib_io_files_list{$_}++; + } + close EXT_LIB; +} + +sub read_icg_no_found() { + my $path = $ENV{'TRICK_BUILD_DIR'}; + open ICG_NO_FOUND, "${path}build/ICG_no_found" or die "Could not open ${path}build/ICG_no_found"; + while () { + chomp; + $icg_no_files_list{$_}++; + } + close ICG_NO_FOUND; +} + +sub file_to_io_cpp($) { + my ($file) = @_; + + $file =~ /(.*)\.[^.]*$/; + my $ret = dirname($1) . "/io_" . basename($1) . ".cpp"; +} + +run_ICG("S_source.hh"); + +# Restore build dir +$ENV{'TRICK_BUILD_DIR'} = $og_trick_build_dir; diff --git a/libexec/trick/trickify_get_swig_data b/libexec/trick/trickify_get_swig_data new file mode 100755 index 000000000..ad3d2aa80 --- /dev/null +++ b/libexec/trick/trickify_get_swig_data @@ -0,0 +1,17 @@ +#!/usr/bin/perl + +use FindBin qw($RealBin); +use lib "$RealBin/pm"; + +use File::Path qw(make_path); +use swig_make; + +use strict; + +read_files_to_process(); + +get_trick_headers(); + +purge_swig_no_files(); + +write_lib_files(); diff --git a/share/doc/trick/data/build_dir_readme b/share/doc/trick/data/build_dir_readme new file mode 100644 index 000000000..d04eb03a9 --- /dev/null +++ b/share/doc/trick/data/build_dir_readme @@ -0,0 +1,4 @@ +S_library_swig + Generated by: make_makefile_swig->write_lib_files() + Use: Metadata only, not used internally by Trick + Contents: The list of headers swigged by Trick. The list is initially generated by get_lib_deps.pm->get_s_source_deps(), using gcc -MM on S_source.hh. The resulting dependency tree is pruned for any paths under TRICK_EXT_LIB_DIRS. Finally, the list is pruned of any "SWIG: (NO)" files. diff --git a/share/trick/makefiles/Makefile.common b/share/trick/makefiles/Makefile.common index 4db13de63..ca44dbb93 100644 --- a/share/trick/makefiles/Makefile.common +++ b/share/trick/makefiles/Makefile.common @@ -3,8 +3,8 @@ CD := cd MV := /bin/mv RM := /bin/rm CP := /bin/cp -MAKE_OUT := $(abspath build/MAKE_out) -MAKE_ERR := $(abspath build/MAKE_err) +MAKE_OUT := $(abspath $(TRICK_BUILD_DIR)build/MAKE_out) +MAKE_ERR := $(abspath $(TRICK_BUILD_DIR)build/MAKE_err) PWD = $(shell /bin/pwd) COLOR = $(1) diff --git a/share/trick/makefiles/trickify.mk b/share/trick/makefiles/trickify.mk index 5c236022e..91bb86d22 100644 --- a/share/trick/makefiles/trickify.mk +++ b/share/trick/makefiles/trickify.mk @@ -88,6 +88,8 @@ # For more information, see: # https://nasa.github.io/trick/documentation/building_a_simulation/Trickified-Project-Libraries +export AM_I_TRICKIFYING_MK=1 + MY_HOME := $(dir $(lastword $(MAKEFILE_LIST))) -include $(TRICKIFY_MAKE_DUMP) @@ -179,7 +181,7 @@ $(IO_OBJECTS:.o=.d): %.d: ; $(SWIG_OBJECTS): %.o: %.cpp $(info $(call COLOR,Compiling) $<) - $(call ECHO_AND_LOG,$(TRICK_CXX) $(TRICK_CXXFLAGS) $(TRICK_SYSTEM_CXXFLAGS) $(PYTHON_INCLUDES) $(TRICK_SWIG_CFLAGS) $(TRICK_SYSTEM_SWIG_CFLAGS) -Wno-unused-parameter -Wno-shadow -c -o $@ $<) + @make -f $(MY_HOME)trickify_swig_rule.mk compile_swig ARG1=$@ ARG2=$< TRICK_CXXFLAGS='$(TRICK_CXXFLAGS)' TRICK_SYSTEM_CXXFLAGS='$(TRICK_SYSTEM_CXXFLAGS)' PYTHON_INCLUDES='$(PYTHON_INCLUDES)' TRICK_SWIG_CFLAGS='$(TRICK_SWIG_CFLAGS)' TRICK_SYSTEM_SWIG_CFLAGS='$(TRICK_SYSTEM_SWIG_CFLAGS)' PARENT_DIR='$(MY_HOME)' $(SWIG_OBJECTS:.o=.cpp): %.cpp: %.i | %.d .trick $(SWIG_OBJECTS:.o=.i) $(info $(call COLOR,SWIGing) $<) @@ -235,8 +237,8 @@ $(TRICKIFY_PYTHON_DIR): $(SWIG_OBJECTS:.o=.cpp) | $(dir $(TRICKIFY_PYTHON_DIR)) $(BUILD_DIR)S_source.d: | $(BUILD_DIR) - $(call ECHO_AND_LOG,$(TRICK_HOME)/bin/trick-ICG $(TRICK_CXXFLAGS) $(TRICK_SYSTEM_CXXFLAGS) $(TRICK_ICGFLAGS) S_source.hh) - $(call ECHO_AND_LOG,$(TRICK_HOME)/$(LIBEXEC)/trick/make_makefile_swig) + $(call ECHO_AND_LOG,$(TRICK_HOME)/$(LIBEXEC)/trick/trickify_get_swig_data) + $(call ECHO_AND_LOG,$(TRICK_HOME)/$(LIBEXEC)/trick/trickify_ICG) $(call ECHO_AND_LOG,$(TRICK_CC) -MM -MP -MT $@ -MF $@ $(TRICK_CXXFLAGS) S_source.hh) -include $(BUILD_DIR)S_source.d diff --git a/share/trick/makefiles/trickify_swig_rule.mk b/share/trick/makefiles/trickify_swig_rule.mk new file mode 100644 index 000000000..a93d7ba07 --- /dev/null +++ b/share/trick/makefiles/trickify_swig_rule.mk @@ -0,0 +1,9 @@ +include $(PARENT_DIR)Makefile.common + +TRICKIFY_FAKE_DEP_PATHS := "" +ifneq ($(wildcard build/),build/trickify/swig/fake_deps_paths) + TRICKIFY_FAKE_DEP_PATHS := $(shell cat build/trickify/swig/fake_deps_paths) +endif + +compile_swig: + $(call ECHO_AND_LOG,$(TRICK_CXX) $(TRICKIFY_FAKE_DEP_PATHS) $(TRICK_CXXFLAGS) $(TRICK_SYSTEM_CXXFLAGS) $(PYTHON_INCLUDES) $(TRICK_SWIG_CFLAGS) $(TRICK_SYSTEM_SWIG_CFLAGS) -Wno-unused-parameter -Wno-shadow -c -o $(ARG1) $(ARG2)) diff --git a/test/SIM_build_dir/RUN_test/unit_test.py b/test/SIM_build_dir/RUN_test/unit_test.py new file mode 100644 index 000000000..f74fee0bf --- /dev/null +++ b/test/SIM_build_dir/RUN_test/unit_test.py @@ -0,0 +1,4 @@ +sandbox.foo.i = 5 +assert sandbox.foo.i == 5 +foo = trick.Foo() +trick.stop(10) diff --git a/test/SIM_build_dir/S_define b/test/SIM_build_dir/S_define new file mode 100644 index 000000000..f770e2a73 --- /dev/null +++ b/test/SIM_build_dir/S_define @@ -0,0 +1,21 @@ +#include "sim_objects/default_trick_sys.sm" +##include "Foo.hh" +##include "Bar.hh" +##include "Baz.hh" + +class Sandbox : public Trick::SimObject { + + public: + + Foo foo; + Bar bar; + Baz baz; + + Sandbox() { + (1, "scheduled") foo.foo(); + } + +}; + + +Sandbox sandbox; diff --git a/test/SIM_build_dir/S_overrides.mk b/test/SIM_build_dir/S_overrides.mk new file mode 100644 index 000000000..6a7455940 --- /dev/null +++ b/test/SIM_build_dir/S_overrides.mk @@ -0,0 +1 @@ +TRICK_CXXFLAGS += -I$(CURDIR)/models diff --git a/test/SIM_build_dir/models/Bar.hh b/test/SIM_build_dir/models/Bar.hh new file mode 100644 index 000000000..877332874 --- /dev/null +++ b/test/SIM_build_dir/models/Bar.hh @@ -0,0 +1,11 @@ +// @trick_parse{everything} + +#include "trick/Event.hh" + +class Bar : public Trick::Event +{ + int process(long long) { return 0; } + void add() { } + void remove() { } + void restart() { } +}; diff --git a/test/SIM_build_dir/models/Baz.hh b/test/SIM_build_dir/models/Baz.hh new file mode 100644 index 000000000..7cdc3309e --- /dev/null +++ b/test/SIM_build_dir/models/Baz.hh @@ -0,0 +1,8 @@ +// @trick_parse{everything} + +class Baz +{ + public: + int i; + int j; +}; diff --git a/test/SIM_build_dir/models/Foo.hh b/test/SIM_build_dir/models/Foo.hh new file mode 100644 index 000000000..61eb80c19 --- /dev/null +++ b/test/SIM_build_dir/models/Foo.hh @@ -0,0 +1,11 @@ +// @trick_parse{everything} + +#include + +class Foo +{ + public: + int i; + + void foo() { std::cout << i++ << '\n'; } +}; diff --git a/test_sims.yml b/test_sims.yml index 02a86f2ee..217eacb17 100644 --- a/test_sims.yml +++ b/test_sims.yml @@ -1,6 +1,9 @@ # Compile only sims SIM_alloc_test: path: test/SIM_alloc_test +SIM_build_dir: + path: test/SIM_build_dir + build_args: "-b Trick_Build_Dir" SIM_anon_enum: path: test/SIM_anon_enum SIM_default_member_initializer: diff --git a/trick_sims/SIM_trickified_demo/models/Core_Model/Ball.cpp b/trick_sims/SIM_trickified_demo/models/Core_Model/Ball.cpp index 063d672a2..c1a4d7e93 100644 --- a/trick_sims/SIM_trickified_demo/models/Core_Model/Ball.cpp +++ b/trick_sims/SIM_trickified_demo/models/Core_Model/Ball.cpp @@ -29,10 +29,9 @@ LIBRARY DEPENDENCY: // Default consructor. Ball::Ball() /* RETURN: -- None. */ { - - // Print out constructor message. - //cout << "In Ball constructor." << endl; - + // Print out constructor message. + std::cout << "In Ball constructor." << std::endl; + dtt.printout(); } // Destructor. diff --git a/trick_sims/SIM_trickified_demo/models/Core_Model/Ball.hh b/trick_sims/SIM_trickified_demo/models/Core_Model/Ball.hh index 66dfc08fb..a92609d15 100644 --- a/trick_sims/SIM_trickified_demo/models/Core_Model/Ball.hh +++ b/trick_sims/SIM_trickified_demo/models/Core_Model/Ball.hh @@ -36,8 +36,9 @@ PROGRAMMERS: #include // Model include files. -#include "BallState.hh" #include "BallForce.hh" +#include "BallState.hh" +#include "TemplateTest.hh" /** @class Ball @brief ball in C++ @@ -72,7 +73,9 @@ class Ball { BallState state; /**< -- Ball state object. */ BallForce force; /**< -- Ball force object. */ + double test_double; + TemplateTest dtt; }; #ifdef SWIG diff --git a/trick_sims/SIM_trickified_demo/trickified/makefile b/trick_sims/SIM_trickified_demo/trickified/makefile index 12978fece..d35e9b52e 100644 --- a/trick_sims/SIM_trickified_demo/trickified/makefile +++ b/trick_sims/SIM_trickified_demo/trickified/makefile @@ -16,6 +16,7 @@ clean_trickify: -rm -f *.a -rm -f *.o -rm -f *.so + -rm -rf tmp_build nuke_trickify: clean_trickify -rm -f S_overrides_trickify.mk diff --git a/trick_source/codegen/Interface_Code_Gen/PrintAttributes.cpp b/trick_source/codegen/Interface_Code_Gen/PrintAttributes.cpp index 9aa72ab0c..189a99443 100644 --- a/trick_source/codegen/Interface_Code_Gen/PrintAttributes.cpp +++ b/trick_source/codegen/Interface_Code_Gen/PrintAttributes.cpp @@ -1,26 +1,45 @@ +#include "PrintAttributes.hh" + +#include "ClassValues.hh" +#include "CommentSaver.hh" +#include "EnumValues.hh" +#include "FieldDescription.hh" +#include "HeaderSearchDirs.hh" +#include "PrintFileContents10.hh" +#include "PrintFileContentsBase.hh" +#include "Utilities.hh" + +#include "clang/Basic/FileManager.h" +#include "clang/Frontend/CompilerInstance.h" -#include #include -#include +#include #include -#include +#include +#include +#include #include #include -#include -#include +#include +#if defined(_WIN32) +#include +#define get_current_dir _getcwd +#else +#include +#define get_current_dir getcwd +#endif -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Basic/FileManager.h" +std::string get_working_directory() +{ + char buff[FILENAME_MAX]; // FILENAME_MAX is defined in + if (get_current_dir(buff, FILENAME_MAX)) + { + return std::string(buff); + } + return ""; +} -#include "PrintAttributes.hh" -#include "PrintFileContentsBase.hh" -#include "PrintFileContents10.hh" -#include "FieldDescription.hh" -#include "HeaderSearchDirs.hh" -#include "CommentSaver.hh" -#include "ClassValues.hh" -#include "EnumValues.hh" -#include "Utilities.hh" +std::string trick_build_dir; PrintAttributes::PrintAttributes(int in_attr_version , HeaderSearchDirs & in_hsd , CommentSaver & in_cs , clang::CompilerInstance & in_ci, bool in_force , bool in_sim_services_flag , @@ -33,6 +52,58 @@ PrintAttributes::PrintAttributes(int in_attr_version , HeaderSearchDirs & in_hsd output_dir( in_output_dir ) { printer = new PrintFileContents10() ; + trickifying = false; + trickifying_mk = false; + if (std::getenv("TRICK_EXCLUDE")) + { + char* env = std::getenv("TRICK_EXCLUDE"); + } + if (std::getenv("TRICK_ICG_EXCLUDE")) + { + char* env = std::getenv("TRICK_ICG_EXCLUDE"); + } + + int iter = 0; + while (iter != iter) + { + iter++; + } + /*if( std::getenv("AM_I_TRICKIFYING") && std::getenv("AM_I_TRICKIFYING_MK") ) { + trickifying = true; + trickifying_mk = true; + std::ifstream trickify_deps("build/trickify/swig/fake_deps_map") ; + if ( !trickify_deps.fail() ) { + std::string in_left; + std::string in_right; + while ( std::getline(trickify_deps, in_left, ':') && std::getline(trickify_deps, in_right) ) { + trickify_src_deps_map.push_back(in_left); + std::cout << "<<<<<<<<<<<<<<<<<<<<<< " << in_left << std::endl; + std::cout << "<<<<<<<<<<<<<<<<<<<<<< " << in_left << std::endl; + std::cout << "<<<<<<<<<<<<<<<<<<<<<< " << in_left << std::endl; + std::cout << "<<<<<<<<<<<<<<<<<<<<<< " << in_left << std::endl; + std::cout << "<<<<<<<<<<<<<<<<<<<<<< " << in_left << std::endl; + std::cout << ">>>>>>>>>>>>>>>>>>>>>> " << in_right << std::endl; + std::cout << ">>>>>>>>>>>>>>>>>>>>>> " << in_right << std::endl; + std::cout << ">>>>>>>>>>>>>>>>>>>>>> " << in_right << std::endl; + std::cout << ">>>>>>>>>>>>>>>>>>>>>> " << in_right << std::endl; + std::cout << ">>>>>>>>>>>>>>>>>>>>>> " << in_right << std::endl; + trickify_src_deps_map.push_back(in_right); + } + } + else { + char cwd[PATH_MAX]; + + if (getcwd(cwd, sizeof(cwd)) != nullptr) { + } else { + perror("getcwd() error"); + } + std::cout << "build/trickify/swig/fake_deps_map no exist =(, " << cwd << std::endl; + } + } + else + { + std::cout << "NO AM_I_TRICKIFYING_MK!" << std::endl; + }*/ } void PrintAttributes::addIgnoreTypes() { @@ -54,7 +125,6 @@ void PrintAttributes::addIgnoreTypes() { /** @details - In order for us to create an io_src file for an include the header must: 1. Reside in a user directory ( not system dirs like /usr/include @@ -114,7 +184,29 @@ static void _mkdir(const char *dir) { } } -bool PrintAttributes::openIOFile(const std::string& header_file_name) { +bool PrintAttributes::openIOFile(const std::string& header_file) +{ + std::string header_file_name = header_file; + + if (trickifying && trickifying_mk) + { + bool found = false; + for (int itr = 0; itr < trickify_src_deps_map.size(); itr += 2) + { + if ((trickify_src_deps_map[itr] == header_file_name) && (itr + 1 < trickify_src_deps_map.size())) + { + found = true; + header_file_name = trickify_src_deps_map[itr + 1]; + break; + } + } + if (!found) + { + // std::cout << "|" << header_file_name << "|" << std::endl; + // return false; + } + } + /** * There are a lot of conditions to be met in order to open an IO file. We store the headers * we have visited so we don't have to retest the them each time a new class/enum is processed. @@ -209,7 +301,7 @@ std::string PrintAttributes::createIOFileName(std::string header_file_name) { } else { //TODO: only use build directory if we are ICG'ing a sim // All files go into a build directory based in the current directory. - io_file_name = std::string("build") + dir_name + "/" + base_name ; + io_file_name = trick_build_dir + std::string("build") + dir_name + "/" + base_name; } } return io_file_name ; @@ -282,7 +374,7 @@ void PrintAttributes::printSieClass( ClassValues * cv ) { xmlFileName = std::string(getenv("TRICK_HOME")) + "/share/trick/xml/sim_services_classes.resource"; #endif } else { - xmlFileName = "build/classes.resource"; + xmlFileName = trick_build_dir + "build/classes.resource"; } std::ofstream ostream(xmlFileName, std::ofstream::app); ostream << " getFullyQualifiedMangledTypeName("__")) << "\">\n"; @@ -349,7 +441,7 @@ void PrintAttributes::createMapFiles() { class_map_function_name = "populate_sim_services_class_map" ; enum_map_function_name = "populate_sim_services_enum_map" ; } else { - map_dir = "build" ; + map_dir = trick_build_dir + "build"; class_map_function_name = "populate_class_map" ; enum_map_function_name = "populate_enum_map" ; } @@ -368,7 +460,8 @@ void PrintAttributes::createMapFiles() { printer->printEnumMapHeader(enum_map_outfile, enum_map_function_name ) ; } -void PrintAttributes::closeMapFiles() { +void PrintAttributes::closeMapFiles(bool print_mode) +{ printer->printClassMapFooter(class_map_outfile) ; class_map_outfile.close() ; @@ -376,12 +469,15 @@ void PrintAttributes::closeMapFiles() { enum_map_outfile.close() ; // If we wrote any new io_src files, move the temporary class and enum map files to new location - if ( out_of_date_io_files.size() > 0 ) { + if (out_of_date_io_files.size() > 0 || print_mode) + { std::ifstream class_map(std::string(map_dir + "/.class_map.cpp").c_str()) ; std::ifstream enum_map(std::string(map_dir + "/.enum_map.cpp").c_str()) ; std::ofstream combined_map(std::string(map_dir + "/class_map.cpp").c_str()) ; combined_map << class_map.rdbuf() << enum_map.rdbuf() ; - } else { + } + else + { remove( std::string(map_dir + "/.class_map.cpp").c_str() ) ; remove( std::string(map_dir + "/.enum_map.cpp").c_str() ) ; } @@ -406,21 +502,33 @@ std::set PrintAttributes::getEmptyFiles() { continue; } + std::string path = almostRealPath(header_file_name.c_str()); + if (visited_files.find(path) != visited_files.end()) + { + continue; + } + visited_files.insert(header_file_name) ; if (isHeaderExcluded(header_file_name)) { continue; } - char* path = almostRealPath(header_file_name.c_str()); emptyFiles.insert(path); - free(path) ; } return emptyFiles; } -//TODO: Move this into PrintFileContents10. void PrintAttributes::printIOMakefile() { + printIOMakefile(all_io_files, ext_lib_io_files, icg_no_files, &out_of_date_io_files); +} + +// TODO: Move this into PrintFileContents10. +void PrintAttributes::printIOMakefile(std::map& all_io_files_ref, + std::set& ext_lib_io_files_ref, + std::vector& icg_no_files_ref, + std::map* out_of_date_io_files_ptr) +{ std::ofstream makefile_io_src ; std::ofstream makefile_ICG ; std::ofstream io_link_list ; @@ -429,13 +537,14 @@ void PrintAttributes::printIOMakefile() { std::ofstream ext_lib ; // Don't create a makefile if we didn't process any files. - if ( out_of_date_io_files.empty() ) { - return ; + if (out_of_date_io_files_ptr != NULL && out_of_date_io_files_ptr->empty()) + { + return; } std::cout << color(INFO, "Writing") << " Makefile_io_src" << std::endl ; - makefile_io_src.open("build/Makefile_io_src") ; + makefile_io_src.open(trick_build_dir + "build/Makefile_io_src"); makefile_io_src << "TRICK_IO_CXXFLAGS += -Wno-invalid-offsetof -Wno-old-style-cast -Wno-write-strings -Wno-unused-variable" << std::endl << std::endl @@ -452,25 +561,28 @@ void PrintAttributes::printIOMakefile() { << "IO_OBJECTS =" ; std::map< std::string , std::string >::iterator mit ; - for ( mit = all_io_files.begin() ; mit != all_io_files.end() ; ++mit ) { + for (mit = all_io_files_ref.begin(); mit != all_io_files_ref.end(); ++mit) + { size_t found ; found = (*mit).second.find_last_of(".") ; makefile_io_src << " \\\n " << (*mit).second.substr(0,found) << ".o" ; } - makefile_io_src << " \\\n build/class_map.o" << std::endl - << std::endl - << "$(IO_OBJECTS): \%.o : \%.cpp | \%.d" << std::endl - << "\t$(PRINT_COMPILE)" << std::endl - << "\t$(call ECHO_AND_LOG,$(TRICK_CXX) $(TRICK_CXXFLAGS) $(TRICK_SYSTEM_CXXFLAGS) $(TRICK_IO_CXXFLAGS) -MMD -MP -c -o $@ $<)" << std::endl - << std::endl - << "$(IO_OBJECTS:.o=.d): ;" << std::endl - << std::endl - << "-include $(IO_OBJECTS:.o=.d)" << std::endl - << std::endl - << "$(S_MAIN): $(IO_OBJECTS)" << std::endl - << std::endl - << "LINK_LISTS += $(LD_FILELIST)build/io_link_list" << std::endl; + makefile_io_src << " \\\n $(TRICK_BUILD_DIR)build/class_map.o" << std::endl + << std::endl + << "$(IO_OBJECTS): \%.o : \%.cpp | \%.d" << std::endl + << "\t$(PRINT_COMPILE)" << std::endl + << "\t$(call ECHO_AND_LOG,$(TRICK_CXX) $(TRICK_CXXFLAGS) $(TRICK_SYSTEM_CXXFLAGS) " + "$(TRICK_IO_CXXFLAGS) -MMD -MP -c -o $@ $<)" + << std::endl + << std::endl + << "$(IO_OBJECTS:.o=.d): ;" << std::endl + << std::endl + << "-include $(IO_OBJECTS:.o=.d)" << std::endl + << std::endl + << "$(S_MAIN): $(IO_OBJECTS)" << std::endl + << std::endl + << "LINK_LISTS += $(LD_FILELIST)" + trick_build_dir + "build/io_link_list" << std::endl; makefile_io_src.close() ; @@ -484,13 +596,14 @@ void PrintAttributes::printIOMakefile() { ICG_process lists all header files to be used by SWIG. */ - makefile_ICG.open("build/Makefile_ICG") ; - io_link_list.open("build/io_link_list") ; - trickify_io_link_list.open("build/trickify_io_link_list") ; - ICG_processed.open("build/ICG_processed") ; - - makefile_ICG << "build/Makefile_io_src:" ; - for ( mit = all_io_files.begin() ; mit != all_io_files.end() ; ++mit ) { + makefile_ICG.open(trick_build_dir + "build/Makefile_ICG"); + io_link_list.open(trick_build_dir + "build/io_link_list"); + trickify_io_link_list.open(trick_build_dir + "build/trickify_io_link_list"); + ICG_processed.open(trick_build_dir + "build/ICG_processed"); + + makefile_ICG << trick_build_dir + "build/Makefile_io_src:"; + for (mit = all_io_files_ref.begin(); mit != all_io_files_ref.end(); ++mit) + { makefile_ICG << " \\\n " << (*mit).first ; size_t found ; found = (*mit).second.find_last_of(".") ; @@ -498,6 +611,7 @@ void PrintAttributes::printIOMakefile() { std::string ssrc = (*mit).second.substr(0,found) ; if(ssrc.substr( ssrc.length()-11, ssrc.length()) != "io_S_source" ) { + // TODO: class_map.o appears to be missing? trickify_io_link_list << (*mit).second.substr(0,found) << ".o" << std::endl ; } ICG_processed << (*mit).first << std::endl ; @@ -510,22 +624,27 @@ void PrintAttributes::printIOMakefile() { } ICG_processed.close() ; - io_link_list << "build/class_map.o" << std::endl ; + io_link_list << trick_build_dir + "build/class_map.o" << std::endl; io_link_list.close() ; trickify_io_link_list.close() ; - ext_lib.open("build/ICG_ext_lib") ; - for ( auto& file : ext_lib_io_files ) { + ext_lib.open(trick_build_dir + "build/ICG_ext_lib"); + for (auto& file : ext_lib_io_files_ref) + { ext_lib << file << std::endl ; } ext_lib.close() ; } -void PrintAttributes::printICGNoFiles() { +void PrintAttributes::printICGNoFiles() { printICGNoFiles(icg_no_files); } + +void PrintAttributes::printICGNoFiles(std::vector& icg_no_files_ref) +{ if ( ! sim_services_flag ) { std::vector< std::string >::iterator it ; - std::ofstream icg_no_outfile("build/ICG_no_found") ; - for ( it = icg_no_files.begin() ; it != icg_no_files.end() ; ++it ) { + std::ofstream icg_no_outfile(trick_build_dir + "build/ICG_no_found"); + for (it = icg_no_files_ref.begin(); it != icg_no_files_ref.end(); ++it) + { icg_no_outfile << (*it) << std::endl ; } icg_no_outfile.close() ; diff --git a/trick_source/codegen/Interface_Code_Gen/PrintAttributes.hh b/trick_source/codegen/Interface_Code_Gen/PrintAttributes.hh index 94796aa95..4676ebf7a 100644 --- a/trick_source/codegen/Interface_Code_Gen/PrintAttributes.hh +++ b/trick_source/codegen/Interface_Code_Gen/PrintAttributes.hh @@ -22,6 +22,8 @@ class HeaderSearchDirs ; class CommentSaver ; class PrintFileContentsBase ; +extern std::string trick_build_dir; + /** This class creates a PrintFileContentsBase class for each include file that we @@ -44,14 +46,22 @@ class PrintAttributes { /** Prints all of the processed classes and enumerations */ virtual void createMapFiles() ; - virtual void closeMapFiles() ; + virtual void closeMapFiles(bool print_mode = false); /** Create makefile for IO files */ virtual void printIOMakefile() ; + /** Create makefile for IO files, specify lists. */ + void printIOMakefile(std::map& all_io_files_ref, + std::set& ext_lib_io_files_ref, std::vector& icg_no_files_ref, + std::map* out_of_date_io_files_re = NULL); + /** Prints list of files that contain ICG:(No) in the Trick header */ virtual void printICGNoFiles() ; + /** Prints list of files that contain ICG:(No) in the Trick header, specify lists. */ + void printICGNoFiles(std::vector& icg_no_files_ref); + /** Prints a class to the io_src file */ virtual void printClass( ClassValues * in_class) ; @@ -145,7 +155,12 @@ class PrintAttributes { std::map< std::string , std::set< std::string > > processed_classes ; /** map of processed enums sorted by file */ std::map< std::string , std::set< std::string > > processed_enums ; - + /** Local copy of the environment variable AM_I_TRICKIFYING */ + bool trickifying; + /** Local copy of the environment variable AM_I_TRICKIFYING_MK */ + bool trickifying_mk; + /** Used for trickify only, will be empty otherwise. Copy of the base sims dependency list */ + std::vector trickify_src_deps_map; } ; #endif diff --git a/trick_source/codegen/Interface_Code_Gen/main.cpp b/trick_source/codegen/Interface_Code_Gen/main.cpp index 2206a7d6e..217ec846f 100644 --- a/trick_source/codegen/Interface_Code_Gen/main.cpp +++ b/trick_source/codegen/Interface_Code_Gen/main.cpp @@ -146,6 +146,94 @@ const char * gcc_version = ""; } #endif } + +void run_print_mode(std::string print_mode_file, PrintAttributes& pa) +{ + std::ifstream file_list(print_mode_file); + std::vector files; + + if (!file_list.fail()) + { + std::string line; + while (std::getline(file_list, line)) + { + files.push_back(line); + } + } + + std::map all_io_files; + std::set empty_files; + std::set ext_lib_io_files; + std::vector icg_no_files; + + std::ifstream all_files_list(trick_build_dir + "build/trickify/ICG_all_file_list"); + std::ifstream all_io_files_list(trick_build_dir + "build/trickify/ICG_all_io_file_list"); + std::ifstream empty_files_list(trick_build_dir + "build/trickify/ICG_empty_file_list"); + std::ifstream ext_files_list(trick_build_dir + "build/trickify/ICG_ext_file_list"); + std::ifstream no_found_list(trick_build_dir + "build/trickify/ICG_no_found_file_list"); + + // Populate io files + if (!all_files_list.fail() && !all_io_files_list.fail()) + { + std::string line_first, line_second; + while (std::getline(all_files_list, line_first) && std::getline(all_io_files_list, line_second)) + { + all_io_files[line_first] = line_second; + } + } + else + { + exit(1); + } + + // Populate empty files + if (!empty_files_list.fail()) + { + std::string line; + while (std::getline(empty_files_list, line)) + { + empty_files.insert(line); + } + } + else + { + exit(1); + } + + // Populate ext libs + if (!ext_files_list.fail()) + { + std::string line; + while (std::getline(ext_files_list, line)) + { + ext_lib_io_files.insert(line); + } + } + else + { + exit(1); + } + + // Populate no-icg found list + if (!no_found_list.fail()) + { + std::string line; + while (std::getline(no_found_list, line)) + { + icg_no_files.push_back(line); + } + } + else + { + exit(1); + } + + pa.printIOMakefile(all_io_files, ext_lib_io_files, icg_no_files); + pa.printICGNoFiles(icg_no_files); + + return; +} + /** Most of the main program is pieced together from examples on the web. We are doing the following: @@ -157,6 +245,13 @@ Most of the main program is pieced together from examples on the web. We are doi -# Parsing the input file. */ int main(int argc, char * argv[]) { + const char* trick_build_dir_ptr = std::getenv("TRICK_BUILD_DIR"); + if (!trick_build_dir_ptr) + { + trick_build_dir_ptr = ""; + } + trick_build_dir = trick_build_dir_ptr; + llvm::cl::SetVersionPrinter([] #if (LIBCLANG_MAJOR >= 6) (llvm::raw_ostream& stream) {stream @@ -173,16 +268,33 @@ int main(int argc, char * argv[]) { * Filter out -W because of LLVM cl option that has been enabled and cannot be disabled in LLVM 10 when linking libclang-cpp.so. * TODO: Troubleshoot or contact LLVM for a fix. */ + bool print_mode = false; + std::string print_mode_file = ""; std::vector filtered_args; for ( unsigned int ii = 0; ii < argc ; ii++ ) { - if( strncmp(argv[ii], "-W", 2) ) { + if (!strncmp(argv[ii], "--printIO", 9)) + { + if (ii + 1 >= argc) + { + std::cout << "Must provide path for print mode." << std::endl; + return 1; + } + filtered_args.push_back(argv[ii]); + std::cout << "ICG Print IO Mode" << std::endl; + print_mode = true; + print_mode_file = argv[ii + 1]; + ii++; + } + else if (strncmp(argv[ii], "-W", 2)) + { filtered_args.push_back(argv[ii]); } } llvm::cl::ParseCommandLineOptions(filtered_args.size(), filtered_args.data()); - if (input_file_names.empty()) { + if (input_file_names.empty() && !print_mode) + { std::cerr << "No header file specified" << std::endl; return 1; } @@ -304,6 +416,14 @@ int main(int argc, char * argv[]) { PrintAttributes printAttributes(attr_version, hsd, cs, ci, force, sim_services_flag, output_dir); + if (print_mode) + { + run_print_mode(print_mode_file, printAttributes); + printAttributes.createMapFiles(); + printAttributes.closeMapFiles(print_mode); + return 0; + } + printAttributes.addIgnoreTypes() ; // Create new class and enum map files if (create_map) {