Forward FIPS DLL implementations from libcrypto DLL under Win32.
[oweals/openssl.git] / util / pl / VC-32.pl
1 #!/usr/local/bin/perl
2 # VC-32.pl - unified script for Microsoft Visual C++, covering Win32,
3 # Win64 and WinCE [follow $FLAVOR variable to trace the differences].
4 #
5
6 $ssl=   "ssleay32";
7
8 my $mwex =" \$(FIPSLIB_D)${o}_chkstk.o \$(FIPSLIB_D)${o}_udivdi3.o \$(FIPSLIB_D)${o}_umoddi3.o";
9
10 if ($fips && !$shlib)
11         {
12         $crypto="libeayfips32";
13         $crypto_compat = "libeaycompat32.lib";
14         }
15 else
16         {
17         $crypto="libeay32";
18         }
19
20 $o='\\';
21 $cp='$(PERL) util/copy.pl';
22 $mkdir='$(PERL) util/mkdir-p.pl';
23 $rm='del /Q';
24
25 $zlib_lib="zlib1.lib";
26
27 # C compiler stuff
28 $cc='cl';
29 if ($FLAVOR =~ /WIN64/)
30     {
31     # Note that we currently don't have /WX on Win64! There is a lot of
32     # warnings, but only of two types:
33     #
34     # C4344: conversion from '__int64' to 'int/long', possible loss of data
35     # C4267: conversion from 'size_t' to 'int/long', possible loss of data
36     #
37     # Amount of latter type is minimized by aliasing strlen to function of
38     # own desing and limiting its return value to 2GB-1 (see e_os.h). As
39     # per 0.9.8 release remaining warnings were explicitly examined and
40     # considered safe to ignore.
41     # 
42     $base_cflags=' /W3 /Gs0 /GF /Gy /nologo -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DDSO_WIN32 -DOPENSSL_SYSNAME_WIN32 -DOPENSSL_SYSNAME_WINNT -DUNICODE -D_UNICODE';
43     $base_cflags.=' -D_CRT_SECURE_NO_DEPRECATE';        # shut up VC8
44     $base_cflags.=' -D_CRT_NONSTDC_NO_DEPRECATE';       # shut up VC8
45     $opt_cflags=' /MD /Ox';
46     $dbg_cflags=' /MDd /Od -DDEBUG -D_DEBUG';
47     $lflags="/nologo /subsystem:console /opt:ref";
48     }
49 elsif ($FLAVOR =~ /CE/)
50     {
51     # sanity check
52     die '%OSVERSION% is not defined'    if (!defined($ENV{'OSVERSION'}));
53     die '%PLATFORM% is not defined'     if (!defined($ENV{'PLATFORM'}));
54     die '%TARGETCPU% is not defined'    if (!defined($ENV{'TARGETCPU'}));
55
56     #
57     # Idea behind this is to mimic flags set by eVC++ IDE...
58     #
59     $wcevers = $ENV{'OSVERSION'};                       # WCENNN
60     die '%OSVERSION% value is insane'   if ($wcevers !~ /^WCE([1-9])([0-9]{2})$/);
61     $wcecdefs = "-D_WIN32_WCE=$1$2 -DUNDER_CE=$1$2";    # -D_WIN32_WCE=NNN
62     $wcelflag = "/subsystem:windowsce,$1.$2";           # ...,N.NN
63
64     $wceplatf =  $ENV{'PLATFORM'};
65     $wceplatf =~ tr/a-z0-9 /A-Z0-9_/d;
66     $wcecdefs .= " -DWCE_PLATFORM_$wceplatf";
67
68     $wcetgt = $ENV{'TARGETCPU'};        # just shorter name...
69     SWITCH: for($wcetgt) {
70         /^X86/          && do { $wcecdefs.=" -Dx86 -D_X86_ -D_i386_ -Di_386_";
71                                 $wcelflag.=" /machine:IX86";    last; };
72         /^ARMV4[IT]/    && do { $wcecdefs.=" -DARM -D_ARM_ -D$wcetgt";
73                                 $wcecdefs.=" -DTHUMB -D_THUMB_" if($wcetgt=~/T$/);
74                                 $wcecdefs.=" -QRarch4T -QRinterwork-return";
75                                 $wcelflag.=" /machine:THUMB";   last; };
76         /^ARM/          && do { $wcecdefs.=" -DARM -D_ARM_ -D$wcetgt";
77                                 $wcelflag.=" /machine:ARM";     last; };
78         /^MIPSIV/       && do { $wcecdefs.=" -DMIPS -D_MIPS_ -DR4000 -D$wcetgt";
79                                 $wcecdefs.=" -D_MIPS64 -QMmips4 -QMn32";
80                                 $wcelflag.=" /machine:MIPSFPU"; last; };
81         /^MIPS16/       && do { $wcecdefs.=" -DMIPS -D_MIPS_ -DR4000 -D$wcetgt";
82                                 $wcecdefs.=" -DMIPSII -QMmips16";
83                                 $wcelflag.=" /machine:MIPS16";  last; };
84         /^MIPSII/       && do { $wcecdefs.=" -DMIPS -D_MIPS_ -DR4000 -D$wcetgt";
85                                 $wcecdefs.=" -QMmips2";
86                                 $wcelflag.=" /machine:MIPS";    last; };
87         /^R4[0-9]{3}/   && do { $wcecdefs.=" -DMIPS -D_MIPS_ -DR4000";
88                                 $wcelflag.=" /machine:MIPS";    last; };
89         /^SH[0-9]/      && do { $wcecdefs.=" -D$wcetgt -D_$wcetgt_ -DSHx";
90                                 $wcecdefs.=" -Qsh4" if ($wcetgt =~ /^SH4/);
91                                 $wcelflag.=" /machine:$wcetgt"; last; };
92         { $wcecdefs.=" -D$wcetgt -D_$wcetgt_";
93           $wcelflag.=" /machine:$wcetgt";                       last; };
94     }
95
96     $cc='$(CC)';
97     $base_cflags=' /W3 /WX /GF /Gy /nologo -DUNICODE -D_UNICODE -DOPENSSL_SYSNAME_WINCE -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DDSO_WIN32 -DNO_CHMOD -I$(WCECOMPAT)/include -DOPENSSL_SMALL_FOOTPRINT';
98     $base_cflags.=" $wcecdefs";
99     $opt_cflags=' /MC /O1i';    # optimize for space, but with intrinsics...
100     $dbg_clfags=' /MC /Od -DDEBUG -D_DEBUG';
101     $lflags="/nologo /opt:ref $wcelflag";
102     }
103 else    # Win32
104     {
105     $base_cflags=' /W3 /WX /Gs0 /GF /Gy /nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DDSO_WIN32';
106     $base_cflags.=' -D_CRT_SECURE_NO_DEPRECATE';        # shut up VC8
107     $base_cflags.=' -D_CRT_NONSTDC_NO_DEPRECATE';       # shut up VC8
108     $opt_cflags=' /MD /Ox /O2 /Ob2';
109     $dbg_cflags=' /MDd /Od -DDEBUG -D_DEBUG';
110     $lflags="/nologo /subsystem:console /opt:ref";
111     }
112 $mlflags='';
113
114 $out_def="out32"; $out_def.='_$(TARGETCPU)' if ($FLAVOR =~ /CE/);
115 $tmp_def="tmp32"; $tmp_def.='_$(TARGETCPU)' if ($FLAVOR =~ /CE/);
116 $inc_def="inc32";
117
118 if ($debug)
119         {
120         $cflags=$dbg_cflags.$base_cflags;
121         $lflags.=" /debug";
122         $mlflags.=' /debug';
123         }
124 else
125         {
126         $cflags=$opt_cflags.$base_cflags;
127         }
128
129 $obj='.obj';
130 $ofile="/Fo";
131
132 # EXE linking stuff
133 $link="link";
134 $rsc="rc";
135 $efile="/out:";
136 $exep='.exe';
137 if ($no_sock)           { $ex_libs=''; }
138 elsif ($FLAVOR =~ /CE/) { $ex_libs='winsock.lib'; }
139 else                    { $ex_libs='wsock32.lib'; }
140
141 if ($FLAVOR =~ /CE/)
142         {
143         $ex_libs.=' $(WCECOMPAT)/lib/wcecompatex.lib';
144         $ex_libs.=' /nodefaultlib:oldnames.lib coredll.lib corelibc.lib' if ($ENV{'TARGETCPU'} eq "X86");
145         }
146 else
147         {
148         $ex_libs.=' gdi32.lib advapi32.lib user32.lib';
149         $ex_libs.=' bufferoverflowu.lib' if ($FLAVOR =~ /WIN64/);
150         }
151
152 # As native NT API is pure UNICODE, our WIN-NT build defaults to UNICODE,
153 # but gets linked with unicows.lib to ensure backward compatibility.
154 if ($FLAVOR =~ /NT/)
155         {
156         $cflags.=" -DOPENSSL_SYSNAME_WINNT -DUNICODE -D_UNICODE";
157         $ex_libs="unicows.lib $ex_libs";
158         }
159 # static library stuff
160 $mklib='lib';
161 $ranlib='';
162 $plib="";
163 $libp=".lib";
164 $shlibp=($shlib)?".dll":".lib";
165 $lfile='/out:';
166
167 $shlib_ex_obj="";
168 $app_ex_obj="setargv.obj" if ($FLAVOR !~ /CE/);
169 if ($nasm) {
170         $asm='nasmw -f win32';
171         $afile='-o ';
172 } else {
173         $asm='ml /Cp /coff /c /Cx';
174         $asm.=" /Zi" if $debug;
175         $afile='/Fo';
176 }
177
178 $bn_asm_obj='';
179 $bn_asm_src='';
180 $des_enc_obj='';
181 $des_enc_src='';
182 $bf_enc_obj='';
183 $bf_enc_src='';
184
185 if (!$no_asm && !$fips)
186         {
187         $bn_asm_obj='crypto\bn\asm\bn_win32.obj';
188         $bn_asm_src='crypto\bn\asm\bn_win32.asm';
189         $des_enc_obj='crypto\des\asm\d_win32.obj crypto\des\asm\y_win32.obj';
190         $des_enc_src='crypto\des\asm\d_win32.asm crypto\des\asm\y_win32.asm';
191         $bf_enc_obj='crypto\bf\asm\b_win32.obj';
192         $bf_enc_src='crypto\bf\asm\b_win32.asm';
193         $cast_enc_obj='crypto\cast\asm\c_win32.obj';
194         $cast_enc_src='crypto\cast\asm\c_win32.asm';
195         $rc4_enc_obj='crypto\rc4\asm\r4_win32.obj';
196         $rc4_enc_src='crypto\rc4\asm\r4_win32.asm';
197         $rc5_enc_obj='crypto\rc5\asm\r5_win32.obj';
198         $rc5_enc_src='crypto\rc5\asm\r5_win32.asm';
199         $md5_asm_obj='crypto\md5\asm\m5_win32.obj';
200         $md5_asm_src='crypto\md5\asm\m5_win32.asm';
201         $sha1_asm_obj='crypto\sha\asm\s1_win32.obj';
202         $sha1_asm_src='crypto\sha\asm\s1_win32.asm';
203         $rmd160_asm_obj='crypto\ripemd\asm\rm_win32.obj';
204         $rmd160_asm_src='crypto\ripemd\asm\rm_win32.asm';
205         $cflags.=" -DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM";
206         }
207
208 if ($shlib && $FLAVOR !~ /CE/)
209         {
210         $mlflags.=" $lflags /dll";
211 #       $cflags =~ s| /MD| /MT|;
212         $lib_cflag=" -D_WINDLL";
213         $out_def="out32dll";
214         $tmp_def="tmp32dll";
215         #
216         # Engage Applink...
217         #
218         $app_ex_obj.=" \$(OBJ_D)\\applink.obj /implib:\$(TMP_D)\\junk.lib";
219         $cflags.=" -DOPENSSL_USE_APPLINK -I.";
220         # I'm open for better suggestions than overriding $banner...
221         $banner=<<'___';
222         @echo Building OpenSSL
223
224 $(OBJ_D)\applink.obj:   ms\applink.c
225         $(CC) /Fo$(OBJ_D)\applink.obj $(APP_CFLAGS) -c ms\applink.c
226 $(OBJ_D)\uplink.obj:    ms\uplink.c ms\applink.c
227         $(CC) /Fo$(OBJ_D)\uplink.obj $(SHLIB_CFLAGS) -c ms\uplink.c
228 $(INCO_D)\applink.c:    ms\applink.c
229         $(CP) ms\applink.c $(INCO_D)\applink.c
230
231 EXHEADER= $(EXHEADER) $(INCO_D)\applink.c
232
233 LIBS_DEP=$(LIBS_DEP) $(OBJ_D)\applink.obj
234 ___
235 $banner .= "CRYPTOOBJ=\$(OBJ_D)\\uplink.obj \$(CRYPTOOBJ)\n";
236         $banner.=<<'___' if ($FLAVOR =~ /WIN64/);
237 CRYPTOOBJ=ms\uptable.obj $(CRYPTOOBJ)
238 ___
239         }
240 elsif ($shlib && $FLAVOR =~ /CE/)
241         {
242         $mlflags.=" $lflags /dll";
243         $lib_cflag=" -D_WINDLL -D_DLL";
244         $out_def='out32dll_$(TARGETCPU)';
245         $tmp_def='tmp32dll_$(TARGETCPU)';
246         }
247
248 $cflags.=" /Fd$out_def";
249
250 sub do_lib_rule
251         {
252         my($objs,$target,$name,$shlib,$ign,$base_addr) = @_;
253         local($ret);
254
255         $taget =~ s/\//$o/g if $o ne '/';
256         my $base_arg;
257         if ($base_addr ne "")
258                 {
259                 $base_arg= " /base:$base_addr";
260                 }
261         else
262                 {
263                 $base_arg = "";
264                 }
265         if ($target =~ /O_CRYPTO/ && $fipsdso)
266                 {
267                 $name = "/def:ms/libeayfips.def";
268                 }
269         elsif ($name ne "")
270                 {
271                 $name =~ tr/a-z/A-Z/;
272                 $name = "/def:ms/${name}.def";
273                 }
274
275 #       $target="\$(LIB_D)$o$target";
276 #       $ret.="$target: $objs\n";
277         if (!$shlib)
278                 {
279 #               $ret.="\t\$(RM) \$(O_$Name)\n";
280                 $ex =' ';
281                 $ret.="$target: $objs\n";
282                 $ex.= $mwex if $fips && !$fipscanisterbuild && $target =~ /O_CRYPTO/;
283                 $ret.="\t\$(MKLIB) $lfile$target @<<\n  $objs $ex\n<<\n";
284                 }
285         else
286                 {
287                 my $ex = "";            
288                 if ($target =~ /O_SSL/)
289                         {
290                         $ex .= " \$(L_CRYPTO)";
291                         #$ex .= " \$(L_FIPS)" if $fipsdso;
292                         }
293                 my $fipstarget;
294                 if ($fipsdso)
295                         {
296                         $fipstarget = "O_FIPS";
297                         }
298                 else
299                         {
300                         $fipstarget = "O_CRYPTO";
301                         }
302
303
304                 if ($name eq "")
305                         {
306                         $ex.=' bufferoverflowu.lib' if ($FLAVOR =~ /WIN64/);
307                         }
308                 elsif ($FLAVOR =~ /CE/)
309                         {
310                         $ex.=' winsock.lib $(WCECOMPAT)/lib/wcecompatex.lib';
311                         }
312                 else
313                         {
314                         $ex.=' unicows.lib' if ($FLAVOR =~ /NT/);
315                         $ex.=' wsock32.lib gdi32.lib advapi32.lib user32.lib';
316                         $ex.=' bufferoverflowu.lib' if ($FLAVOR =~ /WIN64/);
317                         }
318                 $ex.=" $zlib_lib" if $zlib_opt == 1 && $target =~ /O_CRYPTO/;
319
320                 if ($fips && $target =~ /$fipstarget/)
321                         {
322                         $ex.= $mwex unless $fipscanisterbuild;
323                         $ret.="$target: $objs \$(PREMAIN_DSO_EXE)";
324                         $ret.=" ms/\$(LIBFIPS).def" if $fipsdso;
325                         $ret.="\n\tSET FIPS_LINK=\$(LINK)\n";
326                         $ret.="\tSET FIPS_CC=\$(CC)\n";
327                         $ret.="\tSET FIPS_CC_ARGS=/Fo\$(OBJ_D)${o}fips_premain.obj \$(SHLIB_CFLAGS) -c\n";
328                         $ret.="\tSET PREMAIN_DSO_EXE=\$(PREMAIN_DSO_EXE)\n";
329                         $ret.="\tSET FIPS_SHA1_EXE=\$(FIPS_SHA1_EXE)\n";
330                         $ret.="\tSET FIPS_TARGET=$target\n";
331                         $ret.="\tSET FIPSLIB_D=\$(FIPSLIB_D)\n";
332                         $ret.="\t\$(FIPSLINK) \$(MLFLAGS) $base_arg $efile$target ";
333                         $ret.="$name @<<\n  \$(SHLIB_EX_OBJ) $objs ";
334                         $ret.="\$(OBJ_D)${o}fips_premain.obj $ex\n<<\n";
335                         }
336                 else
337                         {
338                         $ret.="$target: $objs";
339                         if ($target =~ /O_CRYPTO/ && $fipsdso)
340                                 {
341                                 $ret .= " \$(O_FIPS)";
342                                 $ex .= " \$(L_FIPS)";
343                                 }
344                         $ret.="\n\t\$(LINK) \$(MLFLAGS) $efile$target $name @<<\n  \$(SHLIB_EX_OBJ) $objs $ex\n<<\n";
345                         }
346
347         $ret.="\tIF EXIST \$@.manifest mt -nologo -manifest \$@.manifest -outputresource:\$@;2\n\n";
348                 }
349         $ret.="\n";
350         return($ret);
351         }
352
353 sub do_link_rule
354         {
355         my($target,$files,$dep_libs,$libs,$standalone)=@_;
356         local($ret,$_);
357         $file =~ s/\//$o/g if $o ne '/';
358         $n=&bname($targer);
359         $ret.="$target: $files $dep_libs\n";
360         if ($standalone)
361                 {
362                 $ret.="  \$(LINK) \$(LFLAGS) $efile$target @<<\n\t";
363                 $ret.= "$mwex advapi32.lib " if ($files =~ /O_FIPSCANISTER/ && !$fipscanisterbuild);
364                 $ret.="$files $libs\n<<\n";
365                 }
366         elsif ($fips && !$shlib)
367                 {
368                 $ret.="\tSET FIPS_LINK=\$(LINK)\n";
369                 $ret.="\tSET FIPS_CC=\$(CC)\n";
370                 $ret.="\tSET FIPS_CC_ARGS=/Fo\$(OBJ_D)${o}fips_premain.obj \$(SHLIB_CFLAGS) -c\n";
371                 $ret.="\tSET PREMAIN_DSO_EXE=\n";
372                 $ret.="\tSET FIPS_TARGET=$target\n";
373                 $ret.="\tSET FIPS_SHA1_EXE=\$(FIPS_SHA1_EXE)\n";
374                 $ret.="\tSET FIPSLIB_D=\$(FIPSLIB_D)\n";
375                 $ret.="\t\$(FIPSLINK) \$(LFLAGS) $efile$target @<<\n";
376                 $ret.="\t\$(APP_EX_OBJ) $files \$(OBJ_D)${o}fips_premain.obj $libs\n<<\n";
377                 }
378         else
379                 {
380                 $ret.="\t\$(LINK) \$(LFLAGS) $efile$target @<<\n";
381                 $ret.="\t\$(APP_EX_OBJ) $files $libs\n<<\n";
382                 }
383         $ret.="\tIF EXIST \$@.manifest mt -nologo -manifest \$@.manifest -outputresource:\$@;1\n\n";
384         return($ret);
385         }
386
387 sub do_rlink_rule
388         {
389         local($target,$files,$dep_libs,$libs)=@_;
390         local($ret,$_);
391
392         $file =~ s/\//$o/g if $o ne '/';
393         $n=&bname($targer);
394         $ret.="$target: $files $dep_libs \$(FIPS_SHA1_EXE)\n";
395         $ret.="\t\$(MKCANISTER) $target <<\n";
396         $ret.="INPUT($files)\n<<\n";
397         $ret.="\t\$(FIPS_SHA1_EXE) $target > ${target}.sha1\n";
398         $ret.="\t\$(PERL) util${o}copy.pl -stripcr fips-1.0${o}fips_premain.c \$(LIB_D)${o}fips_premain.c\n";
399         $ret.="\t\$(CP) fips-1.0${o}fips_premain.c.sha1 \$(LIB_D)${o}fips_premain.c.sha1\n";
400         $ret.="\n";
401         return($ret);
402         }
403
404 sub do_sdef_rule
405         {
406         my $ret = "ms/\$(LIBFIPS).def: \$(O_FIPSCANISTER)\n";
407         $ret.="\t\$(PERL) util/mksdef.pl \$(MLFLAGS) /out:dummy.dll /def:ms/libeay32.def @<<\n  \$(O_FIPSCANISTER)\n<<\n";
408         $ret.="\n";
409         return $ret;
410         }
411
412 1;