Commit | Line | Data |
5aabfad6 |
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; |
e9cb6d14 |
50 | system($command) == 0 or die "system() failed.\n"; |
5aabfad6 |
51 | $command = "gcc -c $init.cc\n"; |
52 | print $command; |
e9cb6d14 |
53 | system($command) == 0 or die "system() failed.\n"; |
5aabfad6 |
54 | |
55 | $command = "echo EXPORTS > $libname.def\n"; |
56 | print $command; |
e9cb6d14 |
57 | system($command) == 0 or die "system() failed.\n"; |
5aabfad6 |
58 | $command = "nm ".join(" ",@objs)." $init.o $fixup.o | grep '^........ [TCD] _' | sed 's/[^_]*_//' >> $libname.def\n"; |
59 | print $command; |
e9cb6d14 |
60 | system($command) == 0 or die "system() failed.\n"; |
5aabfad6 |
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; |
e9cb6d14 |
65 | system($command) == 0 or die "system() failed.\n"; |
5aabfad6 |
66 | |
67 | $command = "dlltool --as=as --dllname $libname.dll --def $libname.def --base-file $libname.base --output-exp $libname.exp\n"; |
68 | print $command; |
e9cb6d14 |
69 | system($command) == 0 or die "system() failed.\n"; |
5aabfad6 |
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; |
e9cb6d14 |
74 | system($command) == 0 or die "system() failed.\n"; |
5aabfad6 |
75 | |
76 | $command = "dlltool --as=as --dllname $libname.dll --def $libname.def --base-file $libname.base --output-exp $libname.exp\n"; |
77 | print $command; |
e9cb6d14 |
78 | system($command) == 0 or die "system() failed.\n"; |
5aabfad6 |
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; |
e9cb6d14 |
83 | system($command) == 0 or die "system() failed.\n"; |
5aabfad6 |
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; |
e9cb6d14 |
88 | system($command) == 0 or die "system() failed.\n"; |
5aabfad6 |
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; |
e9cb6d14 |
94 | system($command) == 0 or die "system() failed.\n"; |
5aabfad6 |
95 | $command = "mv $libname.a $path".$libname.".a\n"; |
96 | print $command; |
e9cb6d14 |
97 | system($command) == 0 or die "system() failed.\n"; |
5aabfad6 |
98 | |
99 | } |
100 | |
101 | } |
102 | else{ # no special processing, just call ld |
103 | $command = "ld $args\n"; |
104 | print $command; |
e9cb6d14 |
105 | system($command) == 0 or die "system() failed.\n"; |
5aabfad6 |
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 | } |