| # -*-perl-*- |
| $description = "Test the load operator."; |
| |
| $details = "Test dynamic loading of modules."; |
| |
| # Don't do anything if this system doesn't support "load" |
| exists $FEATURES{'load'} or return -1; |
| |
| my $cc = get_config('CC'); |
| if (! $cc) { |
| $verbose and print "Skipping load test: no CC defined\n"; |
| return -1; |
| } |
| |
| # First build a shared object |
| # Provide both a default and non-default load symbol |
| |
| unlink(qw(testload.c testload.so)); |
| |
| open(my $F, '> testload.c') or die "open: testload.c: $!\n"; |
| print $F <<'EOF' ; |
| #include "gnumake.h" |
| |
| char* getenv (const char*); |
| |
| int plugin_is_GPL_compatible; |
| |
| int testload_gmk_setup (unsigned int, gmk_floc *); |
| int explicit_setup (unsigned int, gmk_floc *); |
| |
| int |
| testload_gmk_setup (unsigned int abi, gmk_floc *pos) |
| { |
| (void)abi; |
| (void)pos; |
| gmk_eval ("TESTLOAD = implicit", 0); |
| if (getenv("TESTAPI_KEEP")) |
| return -1; |
| return 1; |
| } |
| |
| int |
| explicit_setup (unsigned int abi, gmk_floc *pos) |
| { |
| (void)abi; |
| (void)pos; |
| gmk_eval ("TESTLOAD = explicit", 0); |
| if (getenv("TESTAPI_KEEP")) |
| return -1; |
| return 1; |
| } |
| EOF |
| close($F) or die "close: testload.c: $!\n"; |
| |
| # Make sure we can compile |
| |
| my $cppflags = get_config('CPPFLAGS') . ($srcdir ? " -I$srcdir/src" : ''); |
| my $cflags = get_config('CFLAGS') . ' -fPIC'; |
| my $ldflags = get_config('LDFLAGS') . ' -shared'; |
| my $sobuild = "\"$cc\" $cppflags $cflags $ldflags -o testload.so testload.c"; |
| |
| my $clog = `$sobuild 2>&1`; |
| if ($? != 0) { |
| $verbose and print "Failed to build testload.so:\n$sobuild\n$clog"; |
| return -1; |
| } |
| |
| # TEST 1 |
| run_make_test(q! |
| PRE := $(.LOADED) |
| load testload.so |
| POST := $(.LOADED) |
| all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD) |
| !, |
| '--warn-undefined-variables', "pre= post=testload.so implicit\n"); |
| |
| # TEST 2 |
| # Load using an explicit function |
| run_make_test(q! |
| PRE := $(.LOADED) |
| load ./testload.so(explicit_setup) |
| POST := $(.LOADED) |
| all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD) |
| !, |
| '', "pre= post=testload.so explicit\n"); |
| |
| # TEST 3 |
| # Check multiple loads |
| run_make_test(q! |
| PRE := $(.LOADED) |
| load ./testload.so |
| load testload.so(explicit_setup) |
| POST := $(.LOADED) |
| all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD) |
| !, |
| '', "pre= post=testload.so implicit\n"); |
| |
| # TEST 4 |
| # Check auto-rebuild of loaded file that's out of date |
| utouch(-10, 'testload.so'); |
| touch('testload.c'); |
| |
| run_make_test(q! |
| PRE := $(.LOADED) |
| load ./testload.so |
| POST := $(.LOADED) |
| all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD) |
| testload.so: testload.c ; @echo "rebuilding $@"; !.$sobuild, |
| '', "rebuilding testload.so\npre= post=testload.so implicit\n"); |
| |
| # TEST 5 |
| # Check auto-rebuild of loaded file when it doesn't exist |
| unlink('testload.so'); |
| |
| run_make_test(q! |
| PRE := $(.LOADED) |
| -load ./testload.so(explicit_setup) |
| POST := $(.LOADED) |
| all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD) |
| %.so: %.c ; @echo "rebuilding $@"; !.$sobuild, |
| '', "rebuilding testload.so\npre= post=testload.so explicit\n"); |
| |
| # sv 63044. |
| # Test that the loaded shared object is present in .LOADED when the setup |
| # routine returns -1. |
| $ENV{TESTAPI_KEEP} = 1; |
| run_make_test(q! |
| PRE := $(.LOADED) |
| load testload.so |
| POST := $(.LOADED) |
| all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD) |
| !, |
| '--warn-undefined-variables', "pre= post=testload.so implicit\n"); |
| |
| # Check that we don't auto-rebuild of loaded file that's out of date |
| # if we return -1 from the setup |
| utouch(-10, 'testload.so'); |
| touch('testload.c'); |
| |
| $ENV{TESTAPI_KEEP} = 1; |
| run_make_test(q! |
| PRE := $(.LOADED) |
| load ./testload.so |
| POST := $(.LOADED) |
| all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD) |
| testload.so: testload.c ; @echo "rebuilding $@"; !.$sobuild, |
| '', "pre= post=testload.so implicit\n"); |
| |
| # Check using load as a target or variable name |
| run_make_test(q! |
| load: ; @echo $@ |
| -load&: ; @echo $@ |
| !, |
| "", "load\n"); |
| |
| run_make_test(q! |
| load : ; @echo $@ |
| -load &: ; echo $@ |
| !, |
| "", "load\n"); |
| |
| run_make_test(q! |
| load = @echo $@ |
| all: ; $(load) |
| load |: ; echo $@ |
| !, |
| "", "all\n"); |
| |
| # Verify that load does not start with TAB |
| |
| run_make_test(q! |
| #TAB#load ./testload.so |
| all:;@echo hi |
| !, |
| '', "#MAKEFILE#:2: warning: load lines cannot start with TAB\nhi\n"); |
| |
| run_make_test(q! |
| #TAB#-load ./testload.so |
| all:;@echo hi |
| !, |
| '', "#MAKEFILE#:2: warning: -load lines cannot start with TAB\nhi\n"); |
| |
| # This tells the test driver that the perl test script executed properly. |
| 1; |