Added perl script which will build a Makefile for running C tests on
[wine] / programs / winetest / make_cygwin_makefiles
1 #!/usr/bin/perl -w
2 #
3 # Script to generate a Cygwin makefile for running unit tests.
4 #
5 # Copyright 2002 Geoffrey Hausheer
6 #
7 # This library is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation; either
10 # version 2.1 of the License, or (at your option) any later version.
11 #
12 # This library is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 # Lesser General Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser General Public
18 # License along with this library; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 #
21
22 use strict;
23
24 sub usage;
25 sub fix_dir;
26 sub get_testname;
27 sub create_archive($$\@);
28
29 # set this variable to point to your windows headers
30 my ($windows_includes) ="/usr/include/w32api";
31 # set this variable to your compiler options
32 my($cc_opts)= "-g -O2 -Wall -mpreferred-stack-boundary=2 -D_REENTRANT";
33
34 my($topobjdir);
35 my(@testdirs);
36 my(@gooddirs);
37 my(@ok_list)=();
38 my($dir);
39 my($file);
40 my($afile)="";
41 my($archive)="";
42 # parse command-line options
43 while ($#ARGV >= 0)
44 {
45     my $arg = shift @ARGV;
46     if ($arg eq "-h") { usage; }
47     if ($arg eq "-T")
48     {
49         $topobjdir = shift @ARGV;
50         usage unless (-d $topobjdir);
51         next;
52     }
53     if ($arg eq "-z") {
54       $afile = shift @ARGV;
55       $archive = "z";
56     }
57     if ($arg eq "-g") {
58       $afile = shift @ARGV;
59       $archive = "g";
60     }
61 }
62
63 # check/detect topobjdir
64 # NOTE: Checking for configure is not ideal, but it seems to work
65 if (defined($topobjdir))
66 {
67     unless (-f $topobjdir . "/configure")
68     {
69         printf STDERR "Wrong -T argument, %s/configure does not exist\n", $topobjdir;
70         usage;
71     }
72 }
73 else  # try to detect it automatically
74 {
75     if (-f "./configure") { $topobjdir = "."; }
76     elsif (-f "../configure") { $topobjdir = ".."; }
77     elsif (-f "../../configure") { $topobjdir = "../.."; }
78     elsif (-f "../../../configure") { $topobjdir = "../../.."; }
79     else {
80       printf STDERR "Couldn't locate 'configure', and so no top-level directory\n";
81       usage;
82     }
83 }
84
85 chdir $topobjdir;
86 # Locate all tests
87 open FIND_FH, "find . -type d -name tests -print |";
88 while(<FIND_FH>) {
89   chomp;
90   push @testdirs,$_;
91 }
92 close FIND_FH;
93
94 #start writing the makefile in the root directory
95 open MAKE_FH,">Makefile.cyg";
96 print MAKE_FH "CC = gcc\n";
97 print MAKE_FH "WINDOWS_HEADERS = $windows_includes\n";
98 print MAKE_FH "INCLUDE_DIRS = -I\$(WINDOWS_HEADERS) -I./include\n";
99 print MAKE_FH "CC_OPTS = \$(INCLUDE_DIRS) $cc_opts -include \$(WINDOWS_HEADERS)/windows.h\n";
100
101 # iterate over each 'tests' directory
102 foreach $dir (@testdirs) {
103   my($rootdir);
104   my($testname)=get_testname($dir);
105   $rootdir=fix_dir($dir);
106   unlink("$dir/testlist.c");
107   # Locate all '.c' files that arent 'spec'
108   my(@filelist)=grep(!/\.spec/,glob "$dir/*.c");
109   if(scalar(@filelist)) {
110     # Create a global list of all tests
111     foreach $file (@filelist) {
112       my($newfile);
113       ($newfile = $file) =~ s/c$/ok/;
114       push(@ok_list,$newfile);
115     }
116     # create the testslist.c file for each directory
117     system("./programs/winetest/make_ctests $dir/*.c > $dir/testlist.c");
118     push @filelist,"$dir/testlist.c";
119     push(@gooddirs,$dir);
120     print MAKE_FH "# $dir\n";
121     # List all object files needed for this test
122     print MAKE_FH "TEST_O_FILES_$rootdir = \\\n";
123     foreach $file (@filelist) {
124       $file =~ s/c$/o/;
125       if($file ne $filelist[$#filelist]) {
126         print MAKE_FH " $file\\\n";
127       } else {
128         print MAKE_FH " $file\n";
129       }
130     }
131     print MAKE_FH "TEST_EXE_$rootdir = $dir/$testname.exe\n";
132   }
133 }
134 die "No C files found\n" if (!scalar(@gooddirs));
135 # The prerequisites for the tests are that the .ok fiels get created
136 print MAKE_FH "TEST_OK_FILES = \\\n";
137 foreach $file (@ok_list) {
138   if($file ne $ok_list[$#ok_list]) {
139     print MAKE_FH "     $file\\\n";
140   } else {
141     print MAKE_FH "     $file\n";
142   }
143 }
144 print MAKE_FH "\n";
145 print MAKE_FH "all: \$(TEST_OK_FILES)\n";
146 print MAKE_FH "\n";
147
148 #define how to make the executables
149 foreach $dir (@gooddirs) {
150   my($rootdir)=fix_dir($dir);
151   print MAKE_FH "\$(TEST_EXE_${rootdir}): \$(TEST_O_FILES_${rootdir}) ./programs/winetest/wtmain.o\n";
152   print MAKE_FH "       \$(CC) \$(CC_OPTS) \$(TEST_O_FILES_${rootdir}) ./programs/winetest/wtmain.o -o \$@\n";
153 }
154
155 # define how to make to .ok files
156 foreach $file (@ok_list) {
157   my($dir,$test) = ($file =~ /^(.*[\\\/]+tests)[\\\/]+(.*)\.ok$/);
158   
159   print MAKE_FH "$file: \$(TEST_EXE_". fix_dir($file) . ")\n";
160   print MAKE_FH "       \$< $test && touch \$@\n";
161 }
162 # define how to make the .o files
163
164 print MAKE_FH "%.o: %.c\n";
165 print MAKE_FH " \$(CC) \$(CC_OPTS) -c -o \$@ \$<\n";
166 close MAKE_FH;
167 if($archive ne "") {
168   create_archive($afile,$archive,@testdirs);
169 }
170 exit 0;
171
172
173 sub usage
174 {
175     print STDERR <<EOF;
176
177 Usage: $0 [options]
178
179 Options:
180     -v       verbose mode (can be specified multiple times)
181     -T dir   set Wine tree top directory (autodetected if not specified)
182     -z file  archive (zip) all needed files for test
183     -g file  archive (tar.gz) all needed files for test
184     -h       Show this message
185     NOTE: You can specify either -g or -z but not both
186 EOF
187     exit 1;
188 }
189 sub fix_dir {
190   my($dir)=shift @_;
191   my($rootdir)=($dir =~ /^[^\\\/]*[\\\/]+(.+)[\\\/]+tests/);
192   $rootdir =~ s/[\\\/]+/_/g;
193   return($rootdir);
194 }
195
196 sub get_testname {
197   my($dir)=shift @_;
198   my($testname)=($dir =~ /[\\\/]+([^\\\/]+)[\\\/]+tests/i);
199   return $testname;
200 }
201
202 sub create_archive($$\@) {
203   my($file,$arch,$dirlist)=@_;
204   my($dir);
205   my($cmd);
206   if($arch eq "z") {
207     print "Creating zip archive : $file\n";
208     $cmd = "zip -r $file ";
209   } else {
210     print "Creating tar.gz archive : $file\n";
211    $cmd = "tar -cvzf $file ";
212   }
213   foreach $dir (@$dirlist) {
214     my($cfile);
215     foreach $cfile (grep(!/\.spec/,glob "$dir/*.c")) {
216       $cmd .= "$cfile ";
217     }
218   }
219   $cmd .= " ./programs/winetest/wtmain.c";
220   $cmd .= " ./include/wine";
221   $cmd .= " ./Makefile.cyg";
222   system "$cmd";
223 }