mirror of
https://github.com/nasa/trick.git
synced 2024-12-18 20:57:55 +00:00
Adding back a lost capability, but better this time. The user can now
specify a python module name where the class and functions will be visible in python. With care the user can mimic the C++ namespaces their models reside in, but it isn't perfect nor automatic. It's still pretty neat.
This commit is contained in:
parent
be4372a831
commit
62948308b6
@ -19,6 +19,9 @@ my @files_to_process ;
|
||||
my @ext_lib_files ;
|
||||
my %md5s ;
|
||||
my $verbose_build = exists($ENV{'TRICK_VERBOSE_BUILD'}) ;
|
||||
my %trick_headers ;
|
||||
my %python_modules ;
|
||||
my %python_module_dirs ;
|
||||
|
||||
sub get_paths {
|
||||
my @paths = split /:/ , $ENV{$_[0]} ;
|
||||
@ -140,9 +143,21 @@ sub write_makefile_swig_deps() {
|
||||
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 %trick_header = extract_trick_header( $_[0], do { local( @ARGV, $/ ) = $_[0] ; <> }, 0, 0 ) ;
|
||||
my $result = $trick_header{swig} =~ /^NO$/i ;
|
||||
my $result = $trick_headers{$_[0]}{swig} =~ /^NO$/i ;
|
||||
print "[95mSWIG Skip[39m SWIG: (NO): $_[0]\n" if $verbose_build and $result ;
|
||||
return $result ;
|
||||
}
|
||||
@ -204,10 +219,25 @@ all: \$(TRICK_FIXED_PYTHON)
|
||||
SWIG_I =" ;
|
||||
|
||||
foreach my $file ( @files_to_process ) {
|
||||
(my $swig_file = $file) =~ s/\.[^.]*$/_py.i/ ;
|
||||
print MAKEFILE " \\\n build$swig_file" ;
|
||||
$swig_file =~ s/i$/o/ ;
|
||||
print PY_LINK_LIST "build$swig_file\n" ;
|
||||
if ( !exists $trick_headers{$file}{python_module_dir} ) {
|
||||
(my $swig_file = $file) =~ s/\.[^.]*$/_py.i/ ;
|
||||
print MAKEFILE " \\\n build$swig_file" ;
|
||||
$swig_file =~ s/i$/o/ ;
|
||||
print PY_LINK_LIST "build$swig_file\n" ;
|
||||
}
|
||||
}
|
||||
|
||||
print MAKEFILE "
|
||||
|
||||
SWIG_I_CUSTOM_OUTDIR =" ;
|
||||
|
||||
foreach my $file ( @files_to_process ) {
|
||||
if ( exists $trick_headers{$file}{python_module_dir} ) {
|
||||
(my $swig_file = $file) =~ s/\.[^.]*$/_py.i/ ;
|
||||
print MAKEFILE " \\\n build$swig_file" ;
|
||||
$swig_file =~ s/i$/o/ ;
|
||||
print PY_LINK_LIST "build$swig_file\n" ;
|
||||
}
|
||||
}
|
||||
|
||||
print MAKEFILE "
|
||||
@ -234,9 +264,24 @@ SWIG_SRC = \$(subst .i,.cpp,\$(SWIG_I)) $swig_src_dir/top.cpp
|
||||
\t\@echo \$(SWIG) \$(TRICK_INCLUDE) \$(TRICK_DEFINES) \$(TRICK_VERSIONS) \$(TRICK_SWIG_FLAGS) -c++ -python -includeall -ignoremissing -w201,303,325,362,389,401,451 -outdir trick -o \$@ \$< >> \$(MAKE_OUT)
|
||||
\t\$(ECHO_CMD)\$(SWIG) \$(TRICK_INCLUDE) \$(TRICK_DEFINES) \$(TRICK_VERSIONS) \$(TRICK_SWIG_FLAGS) -c++ -python -includeall -ignoremissing -w201,303,325,362,389,401,451 -outdir trick -o \$@ \$< 2>&1 | \$(TEE) -a \$(MAKE_OUT) ; exit \$\${PIPESTATUS[0]}
|
||||
|
||||
SWIG_SRC_CUSTOM_OUTDIR = \$(subst .i,.cpp,\$(SWIG_I_CUSTOM_OUTDIR))\n" ;
|
||||
|
||||
foreach my $file ( @files_to_process ) {
|
||||
if ( exists $trick_headers{$file}{python_module_dir} ) {
|
||||
(my $swig_file = $file) =~ s/\.[^.]*$/_py.i/ ;
|
||||
(my $cpp_file = $file) =~ s/\.[^.]*$/_py.cpp/ ;
|
||||
print MAKEFILE "
|
||||
build$cpp_file : build$swig_file | trick/$trick_headers{$file}{python_module_dir}
|
||||
\t\$(PRINT_SWIG)
|
||||
\t\@echo \$(SWIG) \$(TRICK_INCLUDE) \$(TRICK_DEFINES) \$(TRICK_VERSIONS) \$(TRICK_SWIG_FLAGS) -c++ -python -includeall -ignoremissing -w201,303,325,362,389,401,451 -outdir trick/$trick_headers{$file}{python_module_dir} -o \$@ \$< >> \$(MAKE_OUT)
|
||||
\t\$(ECHO_CMD)\$(SWIG) \$(TRICK_INCLUDE) \$(TRICK_DEFINES) \$(TRICK_VERSIONS) \$(TRICK_SWIG_FLAGS) -c++ -python -includeall -ignoremissing -w201,303,325,362,389,401,451 -outdir trick/$trick_headers{$file}{python_module_dir} -o \$@ \$< 2>&1 | \$(TEE) -a \$(MAKE_OUT) ; exit \$\${PIPESTATUS[0]}\n";
|
||||
}
|
||||
}
|
||||
|
||||
print MAKEFILE "
|
||||
# SWIG_OBJECTS =================================================================
|
||||
|
||||
SWIG_OBJECTS = \$(subst .cpp,.o,\$(SWIG_SRC)) $swig_src_dir/init_swig_modules.o
|
||||
SWIG_OBJECTS = \$(subst .cpp,.o,\$(SWIG_SRC)) \$(subst .cpp,.o,\$(SWIG_SRC_CUSTOM_OUTDIR)) $swig_src_dir/init_swig_modules.o
|
||||
|
||||
\$(SWIG_OBJECTS): %.o: %.cpp
|
||||
\t\$(PRINT_COMPILE_SWIG)
|
||||
@ -323,6 +368,9 @@ LINK_LISTS += \$(LD_FILELIST)build/py_link_list
|
||||
print INITFILE "import sys\n" ;
|
||||
print INITFILE "import os\n" ;
|
||||
print INITFILE "sys.path.append(os.getcwd() + \"/trick\")\n" ;
|
||||
foreach my $dir ( keys %python_module_dirs ) {
|
||||
print INITFILE "sys.path.append(os.getcwd() + \"/trick/$dir\")\n" ;
|
||||
}
|
||||
|
||||
print INITFILE "\n" ;
|
||||
print INITFILE "import _sim_services\n" ;
|
||||
@ -335,12 +383,16 @@ LINK_LISTS += \$(LD_FILELIST)build/py_link_list
|
||||
|
||||
foreach $f ( @files_to_process, @ext_lib_files ) {
|
||||
print INITFILE "# $f\n" ;
|
||||
print INITFILE "import _m$md5s{$f}\n" ;
|
||||
print INITFILE "from m$md5s{$f} import *\n" ;
|
||||
print INITFILE "combine_cvars(all_cvars, cvar)\n" ;
|
||||
print INITFILE "cvar = None\n\n" ;
|
||||
}
|
||||
|
||||
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" ;
|
||||
@ -357,6 +409,17 @@ LINK_LISTS += \$(LD_FILELIST)build/py_link_list
|
||||
print INITFILE "cvar = all_cvars\n\n" ;
|
||||
close INITFILE ;
|
||||
|
||||
foreach my $dir ( keys %python_module_dirs ) {
|
||||
system("mkdir -p trick/$dir");
|
||||
open MODULE_INITFILE, ">trick/$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 "from m$md5s{$file} import *\n" ;
|
||||
}
|
||||
}
|
||||
close MODULE_INITFILE;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
@ -366,6 +429,7 @@ LINK_LISTS += \$(LD_FILELIST)build/py_link_list
|
||||
read_files_to_process() ;
|
||||
write_makefile_swig_deps() ;
|
||||
|
||||
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() ;
|
||||
|
@ -31,7 +31,7 @@ sub extract_trick_header($$$$) {
|
||||
$header{icg_ignore} = $2 if $trick_header =~ /ICG[ _]IGNORE[ _]TYPE(S)?:[^(]*(.*?)\)([A-Z _\t\n\r]+:|[ \t\n\r]*$)/si ;
|
||||
$header{swig} = $1 if $trick_header =~ /SWIG:[^(]*\((.*?)\)([A-Z _\t\n\r]+:|[ \t\n\r]*$)/si ;
|
||||
$header{default_data} = $1 if $trick_header =~ /DEFAULT[ _]DATA:[^(]*(.*?)\)([A-Z _\t\n\r]+:|[ \t\n\r]*$)/si ;
|
||||
$header{python_module} = $1 if $trick_header =~ /PYTHON[ _]MODULE:[^(]*(.*?)\)([A-Z _\t\n\r]+:|[ \t\n\r]*$)/si ;
|
||||
$header{python_module} = $1 if $trick_header =~ /PYTHON[ _]MODULE:[^(]*\((.*?)\)([A-Z _\t\n\r]+:|[ \t\n\r]*$)/si ;
|
||||
$header{programmers} = $1 if $trick_header =~ /PROGRAMMERS:[^(]*(.*?)\)([A-Z _\t\n\r]+:|[ \t\n\r]*$)/si ;
|
||||
$header{language} = $1 if $trick_header =~ /LANGUAGE:[^(]*(.*?)\)([A-Z _\t\n\r]+:|[ \t\n\r]*$)/si ;
|
||||
|
||||
|
41
test/SIM_python_namespace/RUN_test/unit_test.py
Normal file
41
test/SIM_python_namespace/RUN_test/unit_test.py
Normal file
@ -0,0 +1,41 @@
|
||||
|
||||
from trick.unit_test import *
|
||||
|
||||
def main():
|
||||
trick.stop(1.0)
|
||||
trick_utest.unit_tests.enable()
|
||||
trick_utest.unit_tests.set_file_name( os.getenv("TRICK_HOME") + "/trick_test/SIM_python_namespace.xml" )
|
||||
trick_utest.unit_tests.set_test_name( "PythonNamespace" )
|
||||
test_suite = "python_namespace"
|
||||
|
||||
# normal class methods from S_define
|
||||
ball.foo_food.print_me()
|
||||
ball.foo_inner_food.print_me()
|
||||
ball.bar_food.print_me()
|
||||
print
|
||||
|
||||
# new class from Foo.Food
|
||||
food = trick.Foo.Food()
|
||||
food.print_me()
|
||||
TRICK_EXPECT_EQ( food.fast , 0, test_suite , "first level python namespace" )
|
||||
food.fast = trick.Foo.Burger
|
||||
TRICK_EXPECT_EQ( food.fast , 2, test_suite , "first level python namespace" )
|
||||
|
||||
# new class from Foo.Food.Inner
|
||||
foodinner = trick.Foo.Inner.Food()
|
||||
foodinner.print_me()
|
||||
TRICK_EXPECT_EQ( foodinner.fast , 1, test_suite , "second level python namespace" )
|
||||
foodinner.fast = trick.Foo.Inner.Burger
|
||||
TRICK_EXPECT_EQ( foodinner.fast , 0, test_suite , "second level python namespace" )
|
||||
|
||||
# new class from Foo.Food.Inner
|
||||
bar = trick.Bar.Food()
|
||||
bar.print_me()
|
||||
TRICK_EXPECT_EQ( bar.fast , 2, test_suite , "another first level python namespace" )
|
||||
bar.fast = trick.Bar.Burger
|
||||
TRICK_EXPECT_EQ( bar.fast , 1, test_suite , "another first level python namespace" )
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
26
test/SIM_python_namespace/S_define
Normal file
26
test/SIM_python_namespace/S_define
Normal file
@ -0,0 +1,26 @@
|
||||
/************************TRICK HEADER*************************
|
||||
PURPOSE:
|
||||
(blah blah blah)
|
||||
*************************************************************/
|
||||
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "FooFood.hh"
|
||||
##include "FooInnerFood.hh"
|
||||
##include "BarFood.hh"
|
||||
|
||||
class SimObj : public Trick::SimObject {
|
||||
|
||||
public:
|
||||
Foo::Food foo_food ;
|
||||
Foo::Inner::Food foo_inner_food ;
|
||||
Bar::Food bar_food ;
|
||||
|
||||
/** Constructor to add the jobs */
|
||||
SimObj() {
|
||||
}
|
||||
} ;
|
||||
|
||||
// Instantiations
|
||||
SimObj ball ;
|
||||
|
4
test/SIM_python_namespace/S_overrides.mk
Normal file
4
test/SIM_python_namespace/S_overrides.mk
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
TRICK_CFLAGS += -I./models
|
||||
TRICK_CXXFLAGS += -I./models
|
||||
|
33
test/SIM_python_namespace/models/BarFood.hh
Normal file
33
test/SIM_python_namespace/models/BarFood.hh
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
@file
|
||||
|
||||
@verbatim
|
||||
PURPOSE: (Namespace Test)
|
||||
PYTHON_MODULE: (Bar)
|
||||
@endverbatim
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef BARFOOD_HH
|
||||
#define BARFOOD_HH
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace Bar {
|
||||
|
||||
enum Fast {
|
||||
Pizza,
|
||||
Burger,
|
||||
Taco
|
||||
};
|
||||
|
||||
class Food {
|
||||
public:
|
||||
Food() : fast(Taco) {}
|
||||
void print_me() { std::cout << "Bar::Food::print_me!" << std::endl; }
|
||||
Fast fast;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* _BALL_HH_ */
|
||||
|
33
test/SIM_python_namespace/models/FooFood.hh
Normal file
33
test/SIM_python_namespace/models/FooFood.hh
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
@file
|
||||
|
||||
@verbatim
|
||||
PURPOSE: (Namespace Test)
|
||||
PYTHON_MODULE: (Foo)
|
||||
@endverbatim
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef FOOFOOD_HH
|
||||
#define FOOFOOD_HH
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace Foo {
|
||||
|
||||
enum Fast {
|
||||
Taco,
|
||||
Pizza,
|
||||
Burger
|
||||
};
|
||||
|
||||
class Food {
|
||||
public:
|
||||
Food() : fast(Taco) {}
|
||||
void print_me() { std::cout << "Foo::Food::print_me!" << std::endl; }
|
||||
Fast fast;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* _BALL_HH_ */
|
||||
|
31
test/SIM_python_namespace/models/FooInnerFood.hh
Normal file
31
test/SIM_python_namespace/models/FooInnerFood.hh
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
@file
|
||||
|
||||
@verbatim
|
||||
PURPOSE: (Namespace Test)
|
||||
PYTHON_MODULE: (Foo.Inner)
|
||||
@endverbatim
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef FOOINNERFOOD_HH
|
||||
#define FOOINNERFOOD_HH
|
||||
|
||||
namespace Foo {
|
||||
namespace Inner {
|
||||
enum Fast {
|
||||
Burger,
|
||||
Taco,
|
||||
Pizza
|
||||
};
|
||||
|
||||
class Food {
|
||||
public:
|
||||
Food() : fast(Taco) {}
|
||||
void print_me() { std::cout << "Foo::Inner::Food::print_me!" << std::endl; }
|
||||
Fast fast;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _BALL_HH_ */
|
||||
|
@ -5,6 +5,7 @@ export TRICK_HOST_CPU := $(shell $(TRICK_HOME)/bin/trick-gte TRICK_HOST_CPU)
|
||||
COMPILE_DIRS = \
|
||||
SIM_demo_sdefine \
|
||||
SIM_events \
|
||||
SIM_python_namespace \
|
||||
SIM_rti \
|
||||
SIM_stls \
|
||||
SIM_test_dp \
|
||||
|
Loading…
Reference in New Issue
Block a user