#!/usr/bin/perl -w # # Script to generate a Cygwin/Mingw makefile for running unit tests. # # Copyright 2002 Geoffrey Hausheer # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use strict; sub usage; sub fix_dir; sub get_testname; sub create_archive($$\@); # set this variable to point to your windows headers my ($cygwin_windows_includes) ="/usr/include/w32api"; my ($mingw_windows_includes) ="/mingw/include"; my ($wine_windows_includes) ="./include"; my ($windows_includes)=""; #set the default headers to use my ($default_headers) =\$cygwin_windows_includes; # set this variable to your compiler options my($cc_opts)= "-g -O2 -Wall -mpreferred-stack-boundary=2 -D_REENTRANT"; my($topobjdir); my(@testdirs); my(@gooddirs); my(@ok_list)=(); my($dir); my($file); my($afile)=""; my($archive)=""; # parse command-line options while ($#ARGV >= 0) { my $arg = shift @ARGV; if ($arg eq "-h") { usage; } if ($arg eq "-T") { $topobjdir = shift @ARGV; usage unless (-d $topobjdir); next; } if ($arg eq "-z") { $afile = shift @ARGV; $archive = "z"; } if ($arg eq "-g") { $afile = shift @ARGV; $archive = "g"; } if ($arg eq "-i") { $windows_includes = shift @ARGV; $default_headers = \$windows_includes; } if ($arg eq "-s") { my($sys) = shift @ARGV; if ($sys eq "cygwin") { $default_headers = \$cygwin_windows_includes; } elsif ($sys eq "mingw") { $default_headers = \$mingw_windows_includes; } elsif ($sys eq "wine") { $default_headers = \$wine_windows_includes; } else { usage; } } } # check/detect topobjdir # NOTE: Checking for configure is not ideal, but it seems to work if (defined($topobjdir)) { unless (-f $topobjdir . "/configure") { printf STDERR "Wrong -T argument, %s/configure does not exist\n", $topobjdir; usage; } } else # try to detect it automatically { if (-f "./configure") { $topobjdir = "."; } elsif (-f "../configure") { $topobjdir = ".."; } elsif (-f "../../configure") { $topobjdir = "../.."; } elsif (-f "../../../configure") { $topobjdir = "../../.."; } else { printf STDERR "Couldn't locate 'configure', and so no top-level directory\n"; usage; } } chdir $topobjdir; # Locate all tests open FIND_FH, "find . -type d -name tests -print |"; while() { chomp; push @testdirs,$_; } close FIND_FH; #start writing the makefile in the root directory open MAKE_FH,">Makefile.win"; print MAKE_FH < $dir/testlist.c"); push @filelist,"$dir/testlist.c"; push(@gooddirs,$dir); print MAKE_FH "# $dir\n"; # List all object files needed for this test print MAKE_FH "TEST_O_FILES_$rootdir = \\\n"; foreach $file (@filelist) { $file =~ s/c$/o/; if($file ne $filelist[$#filelist]) { print MAKE_FH " $file\\\n"; } else { print MAKE_FH " $file\n"; } } print MAKE_FH "TEST_EXE_$rootdir = $dir/$testname.exe\n"; } } die "No C files found\n" if (!scalar(@gooddirs)); # The prerequisites for the tests are that the .ok fiels get created print MAKE_FH "\n# .ok result files\n"; print MAKE_FH "TEST_OK_FILES = \\\n"; foreach $file (@ok_list) { if($file ne $ok_list[$#ok_list]) { print MAKE_FH " $file\\\n"; } else { print MAKE_FH " $file\n"; } } print MAKE_FH "\n"; print MAKE_FH "all: \$(TEST_OK_FILES)\n"; print MAKE_FH "\n"; #define how to clean everything up print MAKE_FH "clean:\n"; print MAKE_FH " \$(RM) \$(TEST_OK_FILES)\n"; print MAKE_FH "\n"; print MAKE_FH "distclean:\n"; print MAKE_FH " \$(RM) \$(TEST_OK_FILES)\n"; print MAKE_FH " \$(RM) \$(TEST_O_FILES_wtmain)\n"; foreach $dir (@gooddirs) { my($rootdir)=fix_dir($dir); print MAKE_FH " \$(RM) \$(TEST_EXE_${rootdir}) \$(TEST_O_FILES_${rootdir})\n"; } print MAKE_FH "\n"; #define how to make the executables foreach $dir (@gooddirs) { my($rootdir)=fix_dir($dir); print MAKE_FH "\$(TEST_EXE_${rootdir}): \$(TEST_O_FILES_${rootdir}) \$(TEST_O_FILES_wtmain)\n"; print MAKE_FH " \$(CC) \$(CC_OPTS) \$(TEST_O_FILES_${rootdir}) \$(TEST_O_FILES_wtmain) -o \$@\n"; } # define how to make to .ok files foreach $file (@ok_list) { my($dir,$test) = ($file =~ /^(.*[\\\/]+tests)[\\\/]+(.*)\.ok$/); print MAKE_FH "$file: \$(TEST_EXE_". fix_dir($file) . ")\n"; print MAKE_FH " \$< $test && \$(TOUCH) \$@\n"; } # define how to make the .o files print MAKE_FH "%.o: %.c\n"; print MAKE_FH " \$(CC) \$(CC_OPTS) -c -o \$@ \$<\n"; close MAKE_FH; if($archive ne "") { create_archive($afile,$archive,@testdirs); } exit 0; sub fix_dir { my($dir)=shift @_; my($rootdir)=($dir =~ /^[^\\\/]*[\\\/]+(.+)[\\\/]+tests/); $rootdir =~ s/[\\\/]+/_/g; return($rootdir); } sub get_testname { my($dir)=shift @_; my($testname)=($dir =~ /[\\\/]+([^\\\/]+)[\\\/]+tests/i); return $testname; } sub create_archive($$\@) { my($file,$arch,$dirlist)=@_; my($dir); my($cmd); if($arch eq "z") { print "Creating zip archive : $file\n"; $cmd = "zip -r $file "; } else { print "Creating tar.gz archive : $file\n"; $cmd = "tar -cvzf $file "; } foreach $dir (@$dirlist) { my($cfile); foreach $cfile (grep(!/\.spec/,glob "$dir/*.c")) { $cmd .= "$cfile "; } } $cmd .= " ./programs/winetest/wtmain.c"; $cmd .= " ./include"; $cmd .= " ./Makefile.win"; system "$cmd"; } sub usage { print STDERR <