1 | # |
---|
2 | # Perl script be a wrapper around the gnu ld. When a dll is specified to |
---|
3 | # to be built, special processing is done, else the standard ld is called. |
---|
4 | # |
---|
5 | # Modified 3/14/97 to include the impure_ptr setup routine in init.cc |
---|
6 | # Modified to make dll in current directory then copy to another dir if |
---|
7 | # a path name specified on the command name with the -o parm. |
---|
8 | # |
---|
9 | |
---|
10 | my $args = join(" ",@ARGV); # get args |
---|
11 | my $arg; |
---|
12 | |
---|
13 | my @objs; |
---|
14 | my @flags; |
---|
15 | my $libname; |
---|
16 | my $init = "init"; |
---|
17 | my $fixup = "fixup"; |
---|
18 | |
---|
19 | my $path; |
---|
20 | |
---|
21 | |
---|
22 | sub writefixup; |
---|
23 | sub writeInit; |
---|
24 | |
---|
25 | if( $args=~/\-o (.+?)\.dll/i){ |
---|
26 | $libname = $1; |
---|
27 | # print "libname = <$libname>\n"; |
---|
28 | # Check for path: |
---|
29 | if( $libname =~ /($\.+?\/)(\w+$)/){ |
---|
30 | $path = $1; |
---|
31 | $libname = $2; |
---|
32 | # print "<$path> <$libname>\n"; |
---|
33 | } |
---|
34 | |
---|
35 | foreach $arg(@ARGV){ |
---|
36 | if( $arg=~/\.[oa]$/){ |
---|
37 | push @objs,$arg; |
---|
38 | next; |
---|
39 | } |
---|
40 | if( $arg =~/\-o/ or $arg =~ /.+?\.dll/i ){ |
---|
41 | next; |
---|
42 | } |
---|
43 | push @flags,$arg; |
---|
44 | } |
---|
45 | |
---|
46 | writefixup(); |
---|
47 | writeInit(); |
---|
48 | $command = "gcc -c $fixup.c\n"; |
---|
49 | print $command; |
---|
50 | system($command); |
---|
51 | $command = "gcc -c $init.cc\n"; |
---|
52 | print $command; |
---|
53 | system($command); |
---|
54 | |
---|
55 | $command = "echo EXPORTS > $libname.def\n"; |
---|
56 | print $command; |
---|
57 | system($command); |
---|
58 | $command = "nm ".join(" ",@objs)." $init.o $fixup.o | grep '^........ [TCD] _' | sed 's/[^_]*_//' >> $libname.def\n"; |
---|
59 | print $command; |
---|
60 | system($command); |
---|
61 | |
---|
62 | $command = "ld --base-file $libname.base --dll -o $libname.dll ".join(" ",@objs)." $init.o $fixup.o "; |
---|
63 | $command .= join(" ",@flags)." -e _dll_entry\@12 \n"; |
---|
64 | print $command; |
---|
65 | system($command); |
---|
66 | |
---|
67 | $command = "dlltool --as=as --dllname $libname.dll --def $libname.def --base-file $libname.base --output-exp $libname.exp\n"; |
---|
68 | print $command; |
---|
69 | system($command); |
---|
70 | |
---|
71 | $command = "ld --base-file $libname.base $libname.exp --dll -o $libname.dll ".join(" ",@objs)." $init.o $fixup.o "; |
---|
72 | $command .= join(" ",@flags)." -e _dll_entry\@12 \n"; |
---|
73 | print $command; |
---|
74 | system($command); |
---|
75 | |
---|
76 | $command = "dlltool --as=as --dllname $libname.dll --def $libname.def --base-file $libname.base --output-exp $libname.exp\n"; |
---|
77 | print $command; |
---|
78 | system($command); |
---|
79 | |
---|
80 | $command = "ld $libname.exp --dll -o $libname.dll ".join(" ",@objs)." $init.o $fixup.o "; |
---|
81 | $command .= join(" ",@flags)." -e _dll_entry\@12 \n"; |
---|
82 | print $command; |
---|
83 | system($command); |
---|
84 | |
---|
85 | print "Build the import lib\n"; |
---|
86 | $command = "dlltool --as=as --dllname $libname.dll --def $libname.def --output-lib $libname.a\n"; |
---|
87 | print $command; |
---|
88 | system($command); |
---|
89 | |
---|
90 | # if there was originally a path, copy the dll and a to that location: |
---|
91 | if($path && $path ne "./" && $path."\n" ne "`pwd`"){ |
---|
92 | $command = "mv $libname.dll $path".$libname.".dll\n"; |
---|
93 | print $command; |
---|
94 | system($command); |
---|
95 | $command = "mv $libname.a $path".$libname.".a\n"; |
---|
96 | print $command; |
---|
97 | system($command); |
---|
98 | |
---|
99 | } |
---|
100 | |
---|
101 | } |
---|
102 | else{ # no special processing, just call ld |
---|
103 | $command = "ld $args\n"; |
---|
104 | print $command; |
---|
105 | system($command); |
---|
106 | } |
---|
107 | |
---|
108 | #--------------------------------------------------------------------------- |
---|
109 | sub writeInit{ |
---|
110 | |
---|
111 | open(OUTFILE,">$init.cc") or die("Can't open $init.cc\n"); |
---|
112 | |
---|
113 | print OUTFILE <<'EOF'; |
---|
114 | /* init.cc for WIN32. |
---|
115 | |
---|
116 | Copyright 1996 Cygnus Solutions |
---|
117 | |
---|
118 | This program is free software; you can redistribute it and/or modify |
---|
119 | it under the terms of the GNU General Public License as published by |
---|
120 | the Free Software Foundation; either version 2 of the License, or |
---|
121 | (at your option) any later version. |
---|
122 | |
---|
123 | This program is distributed in the hope that it will be useful, |
---|
124 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
125 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
126 | GNU General Public License for more details. |
---|
127 | |
---|
128 | You should have received a copy of the GNU General Public License |
---|
129 | along with this program; if not, write to the Free Software |
---|
130 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
---|
131 | |
---|
132 | // Added impure_ptr initialization routine. This is needed for any DLL that needs |
---|
133 | // to output to the main (calling) executable's stdout, stderr, etc. This routine |
---|
134 | // needs to be called from the executable using the DLL before any other DLL |
---|
135 | // routines are called. jc 3/14/97 |
---|
136 | |
---|
137 | #include <windows.h> |
---|
138 | |
---|
139 | extern "C" |
---|
140 | { |
---|
141 | int WINAPI dll_entry (HANDLE h, DWORD reason, void *ptr); |
---|
142 | void impure_setup(struct _reent *_impure_ptrMain); |
---|
143 | }; |
---|
144 | |
---|
145 | struct _reent *_impure_ptr; // this will be the Dlls local copy of impure ptr |
---|
146 | |
---|
147 | int WINAPI dll_entry (HANDLE , |
---|
148 | DWORD reason, |
---|
149 | void *) |
---|
150 | { |
---|
151 | switch (reason) |
---|
152 | { |
---|
153 | case DLL_PROCESS_ATTACH: |
---|
154 | break; |
---|
155 | case DLL_PROCESS_DETACH: |
---|
156 | break; |
---|
157 | case DLL_THREAD_ATTACH: |
---|
158 | break; |
---|
159 | case DLL_THREAD_DETACH: |
---|
160 | break; |
---|
161 | } |
---|
162 | return 1; |
---|
163 | } |
---|
164 | |
---|
165 | |
---|
166 | //******************************************** |
---|
167 | // Function to set our local (in this dll) copy of impure_ptr to the |
---|
168 | // main's (calling executable's) impure_ptr |
---|
169 | void impure_setup(struct _reent *_impure_ptrMain){ |
---|
170 | |
---|
171 | _impure_ptr = _impure_ptrMain; |
---|
172 | |
---|
173 | } |
---|
174 | EOF |
---|
175 | |
---|
176 | close OUTFILE; |
---|
177 | |
---|
178 | } |
---|
179 | |
---|
180 | #--------------------------------------------------------------------------- |
---|
181 | sub writefixup{ |
---|
182 | |
---|
183 | open(OUTFILE,">$fixup.c") or die("Can't open $fixup.c\n"); |
---|
184 | |
---|
185 | print OUTFILE <<'EOF'; |
---|
186 | /* This is needed to terminate the list of inport stuff */ |
---|
187 | /* Copied from winsup/dcrt0.cc in the cygwin32 source distribution. */ |
---|
188 | asm(".section .idata$3\n" ".long 0,0,0,0, 0,0,0,0"); |
---|
189 | |
---|
190 | EOF |
---|
191 | close OUTFILE; |
---|
192 | } |
---|