This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Separated the [:foo:] parsing to its own function.
[perl5.git] / cygwin32 / perlld
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) == 0 or die "system() failed.\n";
51         $command = "gcc -c $init.cc\n";
52         print $command; 
53         system($command) == 0 or die "system() failed.\n";
54         
55         $command = "echo EXPORTS > $libname.def\n";
56         print $command; 
57         system($command) == 0 or die "system() failed.\n";
58         $command = "nm ".join(" ",@objs)."  $init.o $fixup.o | grep '^........ [TCD] _' | sed 's/[^_]*_//' >> $libname.def\n";
59         print $command; 
60         system($command) == 0 or die "system() failed.\n";
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) == 0 or die "system() failed.\n";
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) == 0 or die "system() failed.\n";
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) == 0 or die "system() failed.\n";
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) == 0 or die "system() failed.\n";
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) == 0 or die "system() failed.\n";
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) == 0 or die "system() failed.\n";
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) == 0 or die "system() failed.\n";
95                 $command = "mv $libname.a $path".$libname.".a\n";
96                 print $command; 
97                 system($command) == 0 or die "system() failed.\n";
98                 
99         }
100
101 }
102 else{  # no special processing, just call ld
103         $command = "ld $args\n";
104         print $command; 
105         system($command) == 0 or die "system() failed.\n";
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 }