| #!/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(<FIND_FH>) { |
| chomp; |
| push @testdirs,$_; |
| } |
| close FIND_FH; |
| |
| #start writing the makefile in the root directory |
| open MAKE_FH,">Makefile.win"; |
| print MAKE_FH <<EOH ; |
| #Define WINDOWS_HEADERS to point at the directory where windows.h lives |
| #Here are some examples |
| # For Cygwin |
| #WINDOWS_HEADERS = $cygwin_windows_includes |
| # For Mingw |
| #WINDOWS_HEADERS = $mingw_windows_includes |
| # For Wine |
| #WINDOWS_HEADERS = $wine_windows_includes |
| |
| WINDOWS_HEADERS = $$default_headers |
| |
| CC = gcc |
| RM = rm -f |
| TOUCH = touch |
| |
| INCLUDE_DIRS = -I\$(WINDOWS_HEADERS) -I./include |
| CC_OPTS = \$(INCLUDE_DIRS) $cc_opts -include \$(WINDOWS_HEADERS)/windows.h |
| |
| EOH |
| |
| # iterate over each 'tests' directory |
| print MAKE_FH "TEST_O_FILES_wtmain = ./programs/winetest/wtmain.o\n"; |
| foreach $dir (@testdirs) { |
| my($rootdir); |
| my($testname)=get_testname($dir); |
| $rootdir=fix_dir($dir); |
| unlink("$dir/testlist.c"); |
| # Locate all '.c' files that arent 'spec' |
| my(@filelist)=grep(!/\.spec/,glob "$dir/*.c"); |
| if(scalar(@filelist)) { |
| # Create a global list of all tests |
| foreach $file (@filelist) { |
| my($newfile); |
| ($newfile = $file) =~ s/c$/ok/; |
| push(@ok_list,$newfile); |
| } |
| # create the testslist.c file for each directory |
| system("./programs/winetest/make_ctests @filelist > $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 <<EOF; |
| |
| Usage: $0 [options] |
| |
| Options: |
| -v verbose mode (can be specified multiple times) |
| -T dir set Wine tree top directory (autodetected if not specified) |
| -z file archive (zip) all needed files for test |
| -g file archive (tar.gz) all needed files for test |
| -i dir specify directory where windows.h lives |
| -s sys specify system to build on (this sets the default header dir) |
| Valid values for 'sys' are: cygwin, mingw, and wine |
| -h Show this message |
| NOTE: You can specify either -g or -z but not both |
| EOF |
| exit 1; |
| } |