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...