#! /usr/bin/perl -w ## ## Makefile.PL ## ## Copyright (c) 1994-2000 William Setzer ## ## You may distribute under the terms of either the Artistic License ## or the GNU General Public License, as specified in the README file. require 5.005; use strict; #use warnings; Can't use; new since Perl 5.005; use perl -w instead use ExtUtils::MakeMaker; use English; # Here are the arguments defined for this file: # # PANELS -- enable panel functions # MENUS -- enable menus functions # FORMS -- enable forms functions # GEN -- add generation function to Makefile (developers only!) # # Ex: "perl Makefile.PL PANELS MENUS GEN" # Environment variables tell us how one accesses the Curses library # on this system. # # CURSES_LIBTYPE # 'bsd', 'ncurses', or 'ncursesw' on most systems. # In some environments, there are other possibilities. # # CURSES_CFLAGS # CURSES_PANEL_CFLAGS # CURSES_MENUS_CFLAGS # CURSES_FORMS_CFLAGS # contains any includes or defines (-I or -D) that are # needed to compile libcurses applications # # CURSES_LDFLAGS # CURSES_PANEL_LDFLAGS # CURSES_MENUS_LDFLAGS # CURSES_FORMS_LDFLAGS # contains any libraries or library paths (-l or -L) that are # needed to compile libcurses applications. This must be # -l and -L options only -- we parse it. Note that if you # specify something that doesn't result in MakeMaker finding # a library, your value just gets silently ignored -- it # won't show up in the make file. # If these environment variables aren't set, we try in a fairly # stupid fashion to pick them for you, along with a "c-config.h" file. my $libType = $ENV{'CURSES_LIBTYPE'}; my $inc = $ENV{'CURSES_CFLAGS'}; my $libs = $ENV{'CURSES_LDFLAGS'}; my $panel_inc = $ENV{'CURSES_PANEL_CFLAGS'} || ''; my $panel_libs = $ENV{'CURSES_PANEL_LDFLAGS'} || ''; my $menu_inc = $ENV{'CURSES_MENU_CFLAGS'} || ''; my $menu_libs = $ENV{'CURSES_MENU_LDFLAGS'} || ''; my $form_inc = $ENV{'CURSES_FORM_CFLAGS'} || ''; my $form_libs = $ENV{'CURSES_FORM_LDFLAGS'} || ''; # If you want to see examples of what needs to go in the $inc and # $libs variables, check out the `guess_cfg' tables of values below. # In fact, one way to set the variables would be to add or modify an # entry for your 'osname'. If you're not sure what the osname is for # your machine, you can use the following at your command line to # print it out: # # perl -MConfig -le 'print $^O' # # Some lines have multiple versions (such as `freebsd' and `linux'), # representing different versions of curses that an OS might have. # You can pick the version you want by setting the `default' entry. # Here are some notes provided by the hint providers for certain of the # OSes. You should scan them first to see if they apply to you. # # Notes for FreeBSD ncurses: # [Courtesy of "Andrew V. Stesin" ] # FreeBSD-2.0.5 ncurses + mytinfo NOTE! Straight curses works much # better for me! # # Notes for Solaris: # Under 2.3, it was reported that to get the module to compile properly # with gcc, you must add `-DSYSV=1' to $inc. This will disable the # redefinition of memcpy to bcopy that is present in /usr/include/curses.h. # [Courtesy of Dave Blaszyk ] # # $inc also contained "-I/usr/include", but this seems to cause a great # deal of trouble for gcc under perl5.002, so I removed it by default. # I have tested Curses-a9 with perl5.002 and gcc263 and Sun's unbundled # cc on Solaris 2.4 with an empty $inc and had no problems, but your # mileage may vary. # # If you are having trouble compiling under Solaris, try various # combinations of "-I/usr/include" and "-DSYSV=1" in $inc to see if # it fixes things. ## OS default guess for $inc default guess for $libs # my $guess_cfg = { 'aix' => [ '' , '-lcurses -ltermcap' ], 'bsd386' => [ '' , '-lcurses -ltermcap' ], 'bsdos' => [ '' , '-lcurses -ltermcap' ], 'cygwin' => [ '-I/usr/include/ncurses' , '-lncurses' ], 'darwin' => [ '' , '-lcurses' ], 'dec_osf' => [ '' , '-lcurses -ltermcap' ], 'dgux' => [ '' , '-lcurses -ltermcap' ], 'dynixptx' => [ '' , '-lcurses -lc' ], 'freebsd' => { 'bsd' => [ '' , '-lcurses -ltermcap' ], 'ncurses' => [ '' , '-lncurses' ], 'default' => 'bsd' }, 'hpux' => [ '' , '-lcurses -ltermcap' ], # See INSTALL file for information about a different Curses library on HPUX. 'irix' => { 'bsd' => [ '' , '-lcurses -ltermcap' ], 'ncurses' => [ '' , '-lncurses' ], 'default' => 'bsd' }, 'isc' => [ '' , '-lcurses -ltermcap' ], 'linux' => { 'bsd' => [ '' , '-lcurses -ltermcap' ], 'ncurses' => [ '-I/usr/include/ncurses' , '-lncurses' ], 'default' => 'ncurses' }, 'netbsd' => [ '' , '-lcurses -ltermcap' ], 'next' => [ '' , '-lcurses -ltermcap' ], 'openbsd' => [ '' , '-lcurses -ltermcap' ], 'os2' => { 'bsd' => [ '' , '-lcurses -ltermcap' ], 'ncurses' => [ '' , '-lncurses' ], 'default' => 'ncurses' }, 'sco' => [ '' , '-lcurses -ltermcap' ], 'solaris' => [ '' , '-L/usr/ccs/lib -lcurses' ], 'sunos' => { 'bsd' => [ '' , '-lcurses -ltermcap' ], 'sysv' => [ '-I/usr/5include' , '-L/usr/5lib -lcurses' ], 'ncurses' => [ '' , '-lncurses' ], 'default' => 'sysv' }, 'VMS' => [ '' , 'sys$library:vaxccurse.olb' ], 'svr4' => [ '' , '-lcurses' ], 'MSWin32' => { 'borland' => [ '-w- -Id:\bc5\include' , '-Ld:\bc5\lib pdcurses.lib' ], 'visualc' => [ '' , 'pdcurses' ], 'default' => 'visualc' }, '' => undef }; ### ## You shouldn't need to change anything below # my $TRUE = 1; my $FALSE = 0; sub nCursesIsInstalled() { if (-f('/usr/include/ncurses/ncurses.h')) { return $TRUE; } elsif (-f('/usr/include/ncurses.h')) { return $TRUE; } else { return $FALSE; } } sub bsdIsInstalled() { if (-f('/usr/include/curses/curses.h')) { return $TRUE; } elsif (-f('/usr/include/curses.h')) { return $TRUE; } else { return $FALSE; } } sub chooseLibraryType($$) { my ($typeList, $libtypR) = @_; #----------------------------------------------------------------------------- # Assuming this is a platform on which there may be multiple versions of # Curses, choose one. # # Return the choice as $$libtypR. # # We prefer Ncurses, so choose that if it appears to be installed. # If it doesn't, but BSD appears to be installed, we choose that. If # we don't see either, we choose $libtypDefault. #----------------------------------------------------------------------------- if (0) { } elsif ($typeList->{'ncurses'} && nCursesIsInstalled()) { $$libtypR = 'ncurses'; } elsif ($typeList->{'bsd'} && bsdIsInstalled()) { $$libtypR = 'bsd'; } else { $$libtypR = $typeList->{'default'}; } } sub guessAtCursesLocation($$$) { my ($libtypR, $incR, $libsR) = @_; #----------------------------------------------------------------------------- # Return as $$libtypR the type of Curses library we should use, e.g. # 'ncurses', 'ncursesw' or 'bsd'. May be undefined if we don't think # we have to choose between those on this system. # # Return as $$incR the -I option we think is appropriate to get the # Curses interface header files. # # Return as $$libsR the -L and -l options we think are needed to link # the main Curses library (doesn't cover panels/menus/forms). #----------------------------------------------------------------------------- print qq{Making a guess for -I and -L/-l options...\n}; # We need to move away from the inflexible $guess_cfg thing. For # starters, we don't use it when the system looks like one with # wide-character Ncurses. if (-f('/usr/include/ncursesw/ncurses.h')) { $$incR = '-I/usr/include/ncursesw'; $$libsR = '-lncursesw'; $$libtypR = 'ncursesw'; } else { my $guess1 = $guess_cfg->{$OSNAME}; my $libtyp; # typically 'bsd' or 'ncurses'. Undefined if we think # there's no choice of Curses version on this platform. my $guess; if (ref $guess1 eq 'HASH') { # For this platform, we have a choice of Curses library. chooseLibraryType($guess1, \$libtyp); $guess = $guess1->{$libtyp}; } else { $guess = $guess1; } if (not defined $guess) { print STDERR <<"EOW"; I'm sorry, but I could not make a good guess for the includes and libraries that are needed. You will need to set the CURSES_ environment variables as described in the INSTALL file. OSNAME=$OSNAME EOW exit 1; } if (ref $guess ne 'ARRAY') { die "FATAL: internal error: guess_cfg is bad"; } if (!defined($libtyp)) { if (0) { } elsif (-f('/usr/include/ncurses/ncurses.h')) { $inc = '-I/usr/include/ncurses'; } elsif (-f('/usr/include/curses/curses.h')) { $inc = '-I/usr/include/curses'; } elsif (-f('/usr/include/ncurses.h')) { $inc = ''; } elsif (-f('/usr/include/curses.h')) { $inc = ''; } else { $inc = $guess->[0]; } } else { if ($libtyp eq 'ncurses') { if (-f('/usr/include/ncurses/ncurses.h')) { $inc = '-I/usr/include/ncurses'; } elsif (-f('/usr/include/ncurses.h')) { $inc = ''; } else { $inc = $guess->[0]; } } else { if (-f('/usr/include/curses/curses.h')) { $inc = '-I/usr/include/curses'; } elsif (-f('/usr/include/curses.h')) { $inc = ''; } else { $inc = $guess->[0]; } } } $libs = $guess->[1]; $$libtypR = $libtyp; $$incR = $inc; $$libsR = $libs; } print("Guesses:\n"); print(" includes: '$$incR'\n"); print(" libs: '$$libsR'\n"); if (defined($$libtypR)) { print(" Curses type: $$libtypR"); } else { print(" Curses type: irrelevant"); } print("\n"); } sub defaultLibTypeForOs($) { my ($osname) = @_; #----------------------------------------------------------------------------- # Return the default library type for OS named '$osname'; if we don't think # there is a choice of library type on this OS, return undef. #----------------------------------------------------------------------------- my $libType; my $guess = $guess_cfg->{$OSNAME}; if (ref $guess eq 'HASH') { # For this platform, we have a choice of Curses library. $libType = $guess->{'default'}; } return $libType; } # A "library class" is a more abstract categorization than a "library type." # The difference between two library types is just compiler and linker # options to choose the right library, but different library classes # have bigger differences and can have different hints files. The # library class is part of the hint file name. my %libClass = ( 'bsd' => 'bsd', 'ncurses' => 'ncurses', 'ncursesw' => 'ncurses', 'sysv' => 'sysv', 'visualc' => 'visualc', 'borland' => 'borland', ); sub makeConfigH($) { my ($libType) = @_; #----------------------------------------------------------------------------- # $libType is the kind of Curses library we are using - e.g. 'bsd', # 'ncurses', or 'ncursesw'. It may be undefined if there is no # choice on this system. #----------------------------------------------------------------------------- print qq{Making a guess for "c-config.h"...\n}; my $libClass; if (defined($libType)) { $libClass = $libClass{$libType}; if (!defined($libClass)) { print STDERR ("Internal error: invalid library type '$libType' " . "in makeConfigH()\n"); exit 1; } } my $hintsfile; if (defined($libType) && -f("hints/c-$OSNAME.$libType.h")) { $hintsfile = "hints/c-$OSNAME.$libType.h"; } elsif (defined($libClass) && -f("hints/c-$OSNAME.$libClass.h")) { $hintsfile = "hints/c-$OSNAME.$libClass.h"; } else { my $candidate = "hints/c-$OSNAME.h"; if (-f($candidate)) { $hintsfile = $candidate; } else { print STDERR <<"EOW"; I'm sorry, but I couldn't find a hints file that was configured for your OS (named $candidate). You will need to create and configure a "c-config.h" file for yourself. Please see the "INSTALL" directions for pointers on how to do this. EOW exit 1; } } print("Choosing hints file '$hintsfile'\n"); eval "require File::Copy;"; if (! $@) { &File::Copy::copy($hintsfile, "c-config.h"); } else { my $cp; if ($OSNAME eq 'MSWin32') { $cp = "perl -MExtUtils::Command -e cp" } elsif ($OSNAME eq 'VMS') { $cp = "copy/log" } else { $cp = "cp" } my $sys = "$cp $hintsfile c-config.h"; if ($sys =~ m!([^\\:\w/. -])!) { print STDERR <<"EOW"; I'm sorry. I was going to try to create a "c-config.h" for you, but it looks like there are some non-standard characters in the exec string. I'm feeling rather paranoid, so I'll let you look at the line and do it by hand if it looks OK. I wanted to execute a copy and thought I might be able to use: $sys but it has the (possibly) naughty character '$1' in it. ' EOW exit 1; } else { system($sys); } } } sub guessPanelMenuFormLibs($$$$$) { my ($ncursesLibSearch, $libType, $panelLibsR, $menuLibsR, $formLibsR) = @_; my ($panelLibGuess, $menuLibGuess, $formLibGuess); if (defined($libType) && $libType eq "ncursesw") { $panelLibGuess = -lpanelw; $menuLibGuess = -lmenuw; $formLibGuess = -lformw; } else { $panelLibGuess = -lpanel; $menuLibGuess = -lmenu; $formLibGuess = -lform; } $$panelLibsR = "$ncursesLibSearch $panelLibGuess"; $$menuLibsR = "$ncursesLibSearch $menuLibGuess"; $$formLibsR = "$ncursesLibSearch $formLibGuess"; } my $gen; my $panels; my $menus; my $forms; my @argv; while (@ARGV) { my $arg = shift; if ($arg eq 'GEN') { $gen = $arg } elsif ($arg eq 'PANELS') { $panels = $arg } elsif ($arg eq 'MENUS') { $menus = $arg } elsif ($arg eq 'FORMS') { $forms = $arg } else { push @argv, $arg } } @ARGV = @argv; # pass non-Curses arguments to MakeMaker print "GEN function: ", ($gen ? "enabled" : "not applicable"), "\n"; print "PANELS functions: ", ($panels ? "enabled" : "not enabled"), "\n"; print "MENUS functions: ", ($menus ? "enabled" : "not enabled"), "\n"; print "FORMS functions: ", ($forms ? "enabled" : "not enabled"), "\n"; print "\n"; if (defined($inc) && defined($libs)) { # We have the info we need if (!defined($libType)) { $libType = defaultLibTypeForOs($OSNAME); } } elsif (defined($inc) || defined($libs) || defined($libType)) { die("You must specify both CURSES_LDFLAGS and CURSES_CFLAGS " . "environment variables or neither. "); } else { guessAtCursesLocation(\$libType, \$inc, \$libs); } if (not -e "c-config.h") { makeConfigH($libType); } # Major cheese alert. Any -L for the curses library is probably # also needed for the panels library. # my $ncursesLibSearch; $ncursesLibSearch = ''; # initial value while ($libs =~ m{(-L\S+)}g) { $ncursesLibSearch .= $1 . ' '; } guessPanelMenuFormLibs($ncursesLibSearch, $libType, \my $panelGuess, \my $menuGuess, \my $formGuess); if ($panels and not $panel_libs) { $panel_libs = $panelGuess; } if ($menus and not $menu_libs) { $menu_libs = $menuGuess; } if ($forms and not $form_libs) { $form_libs = $formGuess; } # Both Perl and Ncurses have a form.h. We have to include the Perl # header files in our search path, but don't need form.h itself. # Because the Curses form library header directory comes before the # perl header directory in our search path, that isn't normally a # problem. EXCEPT: when there is no specific Curses form library # directory, and the Curses form.h is instead in the general system # search path, e.g. /usr/include/form.h. The system directories come # after the Perl directory in the search. There used to be a # workaround here where we would simply add /usr/include to the front # of the search path, but that is not only gross, but ineffective with # some compilers, which ignore a -I option that adds a directory that # is a system directory (e.g. gcc 3). # To deal with this, we make a rough check for the problem, and if it # appears to exist, we tell the user to fix it. if ($forms and $form_inc !~ m{-I} and -f('/usr/include/form.h')) { print("WARNING: Your Curses form.h file appears to be in the default\n"); print("system search path, which will not work for us because of\n"); print("the conflicting Perl form.h file. This means your 'make' will\n"); print("probably fail unless you fix this, as described in the INSTALL\n"); print("file.\n"); } my $clean = 'CursesDef.h c-config.h cdemo testsym testint testtyp'; my $realc = $gen ? 'list.syms Curses.pm ' . 'CursesFun.c CursesVar.c CursesCon.c CursesTyp.h CursesBoot.c' : ""; my $components = ($panels ? " PANELS " : "") . ($menus ? " MENUS " : "") . ($forms ? " FORMS " : ""); WriteMakefile(NAME => 'Curses', INC => "$panel_inc $menu_inc $form_inc $inc", LIBS => [ "$panel_libs $menu_libs $form_libs $libs" ], H => [ 'CursesDef.h' ], clean => { FILES => $clean }, realclean => { FILES => $realc }, dist => { COMPRESS => 'gzip -9f' }, postamble => { COMPONENTS => $components }, VERSION_FROM => 'Curses.pm', ); sub MY::postamble { my ($this, %args) = @_; my $echo = $OSNAME eq 'VMS' ? 'write sys$output' : 'echo'; my $objext = $OSNAME eq 'MSWin32' ? 'obj' : 'o'; my $mf = <