[comp.os.vms] DECWindows "Dummy" Shareable Images

bcking@io.UUCP (Christine King x4426) (07/06/89)

Somebody besides us must be having this problem, so here's our
solution.  You want to build an executable image that works in
either a VWS (UIS) or a DECWindows environment.  So you write a
bunch of code that detects what's present and takes the appropriate
path at runtime.  But the problem is that the image you have built
has references to DECWindows routines, so if you try to activate it
in on a machine that doesn't have DECWindows installed you get an
error because the runtime libraries are  missing.  (...Although it
wouldn't really be *used* because your code is so smart...)

What you need is a "dummy" DECWindows runtime library, so all the
references will be resolved.  And here's how to build such a library,
not just for DECWindows, but any runtime library.

(PS: This is the first time I've tried anything like this.  I expect
that if it's dumb or overly-complex or wrong I'll get a lot of mail.
Please don't make it hate-mail.)

>>> This comfile assumes you have 'awk'.  <<<

------ cut here ------
$! make_dummy_shr.com
$!
$ Verify_Status = f$verify('Debug'+0)
$!--
$!	Examine SYS$SHARE: sharable image
$!	and make a dummy sharable image that can take its place
$!	at runtime.  Use it to substitute for a sharable image
$!	whose entries really won't be called at runtime, like
$!	for DECW$XLIBSHR on a system without DECW.
$! P1 = sharable image
$! Usage:
$!      @ make_dummy_shr sys$share:decw$transport_common
$!--
$ awk		:= $ D_LIST:[BIN]NAWK
$!
$ Name	= f$parse(P1,,,"NAME")
$!
$ Unique_Num	= f$getjpi("","PID")
$ Unique_Name	:= 'Name'_'Unique_Num'
$ Analyze_Out	:= 'Unique_Name'.ANL
$ Awk_Pgm	:= 'Unique_Name'.AWK
$ Dummy_Pgm	:= 'Name'.MAR
$ Dummy_Obj	:= 'Name'.OBJ
$ Dummy_Opt	:= 'Unique_Name'.OPT
$!
$ analyze/image 'p1 /out='Analyze_Out'
$!
$ create 'Awk_Pgm'
    BEGIN {
        got_entry_point = 0;
	print ";                                                        "
	print "; "Dummy" sharable image            "
	print ";                                                        "
	print " .title	dummy                                           "
	print " .psect	dummy,exe,nowrt,pic,shr,gbl,quad		"
	print ";                                                        "
	print "; macro to generate a transfer vector entry              "
	print ";                                                        "
	print ".macro	make_entry_for_at_offset  routine_name,offset	"
	print ". = start+offset						"
	print " .transfer	routine_name                            "
	print " .mask		routine_name                            "
	print " .entry		routine_name,0				"
	print "  ret							"
	print " .endm							"
	print ";                                                        "
	print "start:							"
	}
    $2 == "Entry"	{ got_entry_point = 1 }
    $1 == "value:"	{ if (got_entry_point) value = $2 }
    $1 == "symbol:"	{ if (got_entry_point) {
				gsub("\"","",$2);
				printf "   make_entry_for_at_offset %s,<^X%04x>\n", $2, value;
				}
			  got_entry_point = 0 }
    END	{ 
	print ";							"
	print ";							"
	print "	.end							"
	}
$!
$!
$ def/user sys$output 'Dummy_Pgm'
$ awk -f 'Awk_Pgm'  'Analyze_Out'
$!
$ macro/list 'Dummy_Pgm'
$!
$ create 'Awk_Pgm'
    BEGIN	{ got_id = 0 }
    ( $1 " " $2 " " $3 ) == "Fixed Header Information" { got_id = 1 }
    ( $1 " " $2 " " $3 " " $4 ) == "global section major id:" { \
	if ( got_id ) {
	    gsub ("'","",$5);
	    gsub ("'","",$8);
	    printf "gsmatch = lequal,%s %s\n", $5, $8
	    }
	got_id = 0
	}
    END		{}
$!
$ def/user sys$output 'Dummy_Opt'
$ awk -f 'Awk_Pgm'  'Analyze_Out'
$!
$ link /map /full /share 'Dummy_Obj', 'Dummy_Opt'/opt
$!==
$ EXIT:
$ My_Status = $status
$ delete 'Unique_Name'.*;*
$ delete 'Name'.MAR;*,.OBJ;*,.LIS;*,.MAP;*
$ exit 'My_Status' + 0*f$verify('Verify_Status')
----- that's all ------



-- 
MONIKER:	Christine King
UUCP:		...{mit-eddie,ihnp4!harvard!bbn,sun!sunne}!ileaf!bcking
PHONE:		(617) 577-9800
USMAIL:		Interleaf Inc, Ten Canal Park, Cambridge MA 02141

tedcrane@batcomputer.tn.cornell.edu (Ted Crane) (07/15/89)

In article <1140@io.UUCP> bcking@io.UUCP (Christine King x4426) writes:
>Somebody besides us must be having this problem, so here's our
>solution.  You want to build an executable image that works in
>either a VWS (UIS) or a DECWindows environment.  So you write a
>bunch of code that detects what's present and takes the appropriate
>path at runtime.  But the problem is that the image you have built

Another way to go about this is to use the VMS routine LIB$FIND_IMAGE_SYMBOL.
After you have determined that you are running w/ UIS or DECwindows, you
use this routine to look up the transfer address of every routine you
need to use.  Since you are passing string arguments to FIND_IMAGE_SYMBOL,
there are no "real" global references in your program.  Thus, neither
the UIS or DECwindows sharable images are linked to your program (the 
first call to FIND_IMAGE_SYMBOL for a given image will load the appropriate
image and merge it into your address space).

Yes, this is messy.  Don't complain to me, though, I just thought I'd
mention it...