#!/usr/bin/perl # # Usage: makemake { {}} # # Generate a Makefile from the sources in the current directory. The source # files may be in either C, FORTRAN 77, Fortran 90 or some combination of # these languages. If the F90 compiler specified is cray or parasoft, then # the Makefile generated will conform to the conventions of these compilers. # To run makemake, it will be necessary to modify the first line of this script # to point to the actual location of Perl on your system. # # Written by Michael Wester February 16, 1995 # Cotopaxi (Consulting), Albuquerque, New Mexico # open(MAKEFILE, "> AA_make"); # #print MAKEFILE "PROG =\t$ARGV[0]\n\n"; # # Misc print MAKEFILE "VPATH=../src/IOSERVER:../src/XMLIO\n"; print MAKEFILE "MAKE_NAM = \$(MAKE)\n"; print MAKEFILE "ifneq (\$(MAKE_NAM),\$(M_K))\n"; print MAKEFILE " \@\$(error You must invoke this Makefile with the \$(M_K) command)\n"; print MAKEFILE "endif\n"; print MAKEFILE "USER_DIR = \$(shell /bin/pwd)\n"; print MAKEFILE "MAKE_DIR = '??'\n"; print MAKEFILE "ifneq (\$(USER_DIR),\$(MAKE_DIR))\n"; print MAKEFILE " \@\$(error You must invoke this Makefile from its directory)\n"; print MAKEFILE "endif\n"; print MAKEFILE "#-\n"; print MAKEFILE "#-Q- sx6nec F_O := \$(F_O) -Wf,-ptr byte\n"; print MAKEFILE "#-Q- sx8brodie F_O := \$(F_O) -Wf,-ptr byte\n"; print MAKEFILE "#-Q- sx8mercure F_O := \$(F_O) -Wf,-ptr byte\n"; print MAKEFILE "#-Q- sx9mercure F_O := \$(F_O) -Wf,-ptr byte\n"; print MAKEFILE "#-Q- sxdkrz F_O := \$(F_O) -Wf,-ptr byte\n"; print MAKEFILE "#-Q- es2 F_O := \$(F_O) -Wf,-ptr byte\n"; print MAKEFILE "#-Q- aix6 F_O = \$(F_P) -O3 -qextname -qsuffix=cpp=F90 -qsuffix=f=f90 -qmoddir=\$(MODDIR) -I \$(MODDIR)\n"; print MAKEFILE "#-Q- aix F_O = \$(F_P) -O3 -qextname -qsuffix=cpp=F90 -qsuffix=f=f90 -qmoddir=\$(MODDIR) -I \$(MODDIR)\n"; print MAKEFILE "#-Q- osxxlf F_O = \$(F_P) -O3 -qextname -qsuffix=cpp=F90 -qsuffix=f=f90 -qmoddir=\$(MODDIR) -I \$(MODDIR)\n"; print MAKEFILE "F_O := \$(F_O) -I../../../lib\n"; print MAKEFILE "P_O := \$(P_O) -traditional\n"; print MAKEFILE "#-Q- aix6 L_O = \$(F_P) -q64 -O3\n"; print MAKEFILE "#-Q- aix L_O = \$(F_P) -q64 -O3\n"; print MAKEFILE "prefix=''\n"; print MAKEFILE "#-Q- aix6 prefix='-WF,'\n"; print MAKEFILE "#-Q- aix prefix='-WF,'\n"; print MAKEFILE "override P_P := \$(P_P:\%=\$(prefix)\%)\n\n"; print MAKEFILE "#---------------------------------------------------------------------\n"; print MAKEFILE "#- Create libioserver and libxmlio\n"; print MAKEFILE "#---------------------------------------------------------------------\n\n"; print MAKEFILE ".PRECIOUS : \$(MODEL_LIB1) \$(MODEL_LIB2)\n"; print MAKEFILE "SXMODEL_LIB1 = \$(MODEL_LIB1)\n"; print MAKEFILE "SXMODEL_LIB2 = \$(MODEL_LIB2)\n"; print MAKEFILE "ifeq (\$(L_X),1)\n"; print MAKEFILE "SXMODEL_LIB1 = \$(LIBDIR)/libsxioserver.a\n"; print MAKEFILE "SXMODEL_LIB2 = \$(LIBDIR)/libsxxmlio.a\n"; print MAKEFILE ".PRECIOUS : \$(SXMODEL_LIB1) \$(SXMODEL_LIB2)\n"; print MAKEFILE "endif\n\n"; # Source listing #IOSERVER print MAKEFILE "MODS1 =\t"; @srcs = < ../src/IOSERVER/*.F90 ../src/IOSERVER/*.f90>; &PrintWords(8, 0, @srcs); print MAKEFILE "\n\n"; # # Object listing # print MAKEFILE "OBJSMODS1 =\t"; @objs = @srcs; foreach (@objs) { s/\.[^.]+$/.o/ }; foreach $objs (@objs) { @tab = split('/', $objs); $objs = $tab[$#tab] ; if( "$objs" eq 'server.o' ){ $objs = ''}; }; &PrintWords(8, 0, @objs); print MAKEFILE "\n\n"; # Source listing #XMLIO print MAKEFILE "MODS2 =\t"; @srcs = < ../src/XMLIO/*.F90 ../src/XMLIO/*.f90>; &PrintWords(8, 0, @srcs); print MAKEFILE "\n\n"; # # Object listing # print MAKEFILE "OBJSMODS2 =\t"; @objs = @srcs; foreach (@objs) { s/\.[^.]+$/.o/ }; foreach $objs (@objs) { @tab = split('/', $objs); $objs = $tab[$#tab] ; if( "$objs" eq 'test_xmlio.o' ){ $objs = ''}; }; &PrintWords(8, 0, @objs); print MAKEFILE "\n\n"; # # make # print MAKEFILE ".SUFFIXES: .f90 .F90\n\n"; print MAKEFILE "all: libioipsl libxmlf90 dirxml \$(MODEL_LIB2)(\$(OBJSMODS2)) key \$(MODEL_LIB1)(\$(OBJSMODS1)) server.o EXEC_BIN\n"; print MAKEFILE "\t\@echo IOSERVER is OK\n\n"; # mpi or not print MAKEFILE "key :\n"; print MAKEFILE "\t\-\@if [ \"`cat KEY_CPP`\" \!= \"\$(P_P)\" ] \; then \\\n"; print MAKEFILE "\techo \"\$(P_P)\" > KEY_CPP \; fi\n\n"; # Main program print MAKEFILE "ifneq (,\$(findstring NO_MPI,\$(P_P)))\n"; print MAKEFILE "EXEC_BIN :\n"; print MAKEFILE "server.o :\n"; print MAKEFILE "else\n"; print MAKEFILE "EXEC_BIN : server.o\n"; print MAKEFILE "\t\$(F_L) \$(L_O) -o ../../../bin/ioserver server.o \$(MODEL_LIB1) \$(MODEL_LIB2) ../../../lib/libioipsl.a \$(NCDF_LIB) ../../../lib/libxmlio_server/libxmlf90.a\n"; print MAKEFILE "server.o : ../src/IOSERVER/server.f90\n"; print MAKEFILE "\t\@\$(F_C) \$(F_O) -c ../src/IOSERVER/server.f90\n"; print MAKEFILE "endif\n\n"; # .f90 -> .o # print MAKEFILE "#Rules for ioserver\n"; print MAKEFILE "#---- Using VPATH instead \$(MODEL_LIB1)(%.o): ../src/IOSERVER/%.f90\n"; print MAKEFILE "\$(MODEL_LIB1)(%.o): %.f90\n"; print MAKEFILE "\t\$(F_C) \$(F_O) -I../src/XMLIO -I../src/IOSERVER -I\$(NCDF_INC) \$<\n"; print MAKEFILE "\t\$(A_C) \$(MODEL_LIB1) \$*.o\n"; print MAKEFILE "ifeq (\$(L_X),1)\n"; print MAKEFILE "\t\$(A_X) \$(SXMODEL_LIB1) \$*.o\n"; print MAKEFILE "endif\n"; print MAKEFILE "#-Q- sgi6 mv \$(shell echo \$* | tr '[:lower:]' '[:upper:]').mod \$(MODDIR)\n"; print MAKEFILE "ifeq (\$(M_M),1)\n"; print MAKEFILE "\t\@mv -f *.mod \$(MODDIR) 2> /dev/null || true\n"; print MAKEFILE "endif\n"; print MAKEFILE "\t\$(RM) \$*.o\n\n"; print MAKEFILE "#Rules for ioserver\n"; #print MAKEFILE "\$src/IOSERVER/%.f90: ../src/IOSERVER/%.F90\n"; #print MAKEFILE "\t@\$(P_C) \$(P_O) \$(P_P) src/IOSERVER/\$(*F).F90 > src/IOSERVER/\$(*F).f90\n\n"; print MAKEFILE "#---- Using VPATH instead \$(MODEL_LIB1)(%.o): ../src/IOSERVER/%.F90\n"; print MAKEFILE "\$(MODEL_LIB1)(%.o): %.F90 KEY_CPP\n"; print MAKEFILE "\t\$(F_C) \$(F_O) \$(P_P) -I\$(NCDF_INC) -I../src/XMLIO -I../src/IOSERVER \$<\n"; print MAKEFILE "\t\$(A_C) \$(MODEL_LIB1) \$*.o\n"; print MAKEFILE "ifeq (\$(L_X),1)\n"; print MAKEFILE "\t\$(A_X) \$(SXMODEL_LIB1) \$*.o\n"; print MAKEFILE "endif\n"; print MAKEFILE "#-Q- sgi6 mv \$(shell echo \$* | tr '[:lower:]' '[:upper:]').mod \$(MODDIR)\n"; print MAKEFILE "ifeq (\$(M_M),1)\n"; print MAKEFILE "\t\@mv -f *.mod \$(MODDIR) 2> /dev/null || true\n"; print MAKEFILE "endif\n"; print MAKEFILE "\t\$(RM) \$*.o\n\n"; print MAKEFILE "#Rules for xmlio\n"; print MAKEFILE "#---- Using VPATH instead \$(MODEL_LIB1)(%.o): ../src/XMLIO/%.F90\n"; print MAKEFILE "\$(MODEL_LIB2)(%.o): %.f90\n"; print MAKEFILE "\t\$(F_C) \$(F_O) -I\$(NCDF_INC) -I../src/XMLIO \$<\n"; print MAKEFILE "\t\$(A_C) \$(MODEL_LIB2) \$*.o\n"; print MAKEFILE "ifeq (\$(L_X),1)\n"; print MAKEFILE "\t\$(A_X) \$(SXMODEL_LIB2) \$*.o\n"; print MAKEFILE "endif\n"; print MAKEFILE "#-Q- sgi6 mv \$(shell echo \$* | tr '[:lower:]' '[:upper:]').mod \$(MODDIR)\n"; print MAKEFILE "ifeq (\$(M_M),1)\n"; print MAKEFILE "\t\@mv -f *.mod \$(MODDIR) 2> /dev/null || true\n"; print MAKEFILE "endif\n"; print MAKEFILE "\t\$(RM) \$*.o\n\n"; print MAKEFILE "dirxml: \n"; print MAKEFILE "\t\@if [ ! -d ../../../lib/libxmlio_server ] ; then mkdir ../../../lib/libxmlio_server ; fi\n\n"; print MAKEFILE "# IOIPSL library\n"; print MAKEFILE "libioipsl :\n"; print MAKEFILE "\t(cd ../../IOIPSL/src ; \$(M_K) -f Makefile )\n\n"; print MAKEFILE "# XMLF90 library\n"; print MAKEFILE "libxmlf90 :\n"; print MAKEFILE "\t(cd ../../XMLF90/external ; \$(M_K) -f Makefile )\n\n"; # # make clean # print MAKEFILE "clean:\n"; print MAKEFILE "\t\$(RM) *.*~ Makefile~ core *.o *.mod i.*.L *.L\n"; print MAKEFILE "\t\$(RM) server.o \$(MODEL_LIB1) \$(MODEL_LIB2)\n\n"; # # # Dependency listings # &MakeDependsf90($ARGV[1],IOSERVER,MODEL_LIB1); &MakeDependsf90($ARGV[1],XMLIO,MODEL_LIB2); &MakeDepends("*.f *.F", '^\s*include\s+["\']([^"\']+)["\']'); &MakeDepends("*.c", '^\s*#\s*include\s+["\']([^"\']+)["\']'); # # &PrintWords(current output column, extra tab?, word list); --- print words # nicely # sub PrintWords { local($columns) = 78 - shift(@_); local($extratab) = shift(@_); local($wordlength); # print MAKEFILE @_[0]; $columns -= length(shift(@_)); foreach $word (@_) { $wordlength = length($word); if ($wordlength + 1 < $columns) { print MAKEFILE " $word"; $columns -= $wordlength + 1; } else { # # Continue onto a new line # if ($extratab) { print MAKEFILE " \\\n\t\t$word"; $columns = 62 - $wordlength; } else { print MAKEFILE " \\\n\t$word"; $columns = 70 - $wordlength; } } } } # # &LanguageCompiler(compiler, sources); --- determine the correct language # compiler # sub LanguageCompiler { local($compiler) = &toLower(shift(@_)); local(@srcs) = @_; # if (length($compiler) > 0) { CASE: { grep(/^$compiler$/, ("fc", "f77")) && do { $compiler = "FC"; last CASE; }; grep(/^$compiler$/, ("cc", "c")) && do { $compiler = "CC"; last CASE; }; $compiler = "F90"; } } else { CASE: { grep(/\.f90$/, @srcs) && do { $compiler = "F90"; last CASE; }; grep(/\.(f|F)$/, @srcs) && do { $compiler = "FC"; last CASE; }; grep(/\.c$/, @srcs) && do { $compiler = "CC"; last CASE; }; $compiler = "???"; } } $compiler; } # # &toLower(string); --- convert string into lower case # sub toLower { local($string) = @_[0]; $string =~ tr/A-Z/a-z/; $string; } # # &uniq(sorted word list); --- remove adjacent duplicate words # sub uniq { local(@words); foreach $word (@_) { if ($word ne $words[$#words]) { push(@words, $word); } } @words; } # # &MakeDepends(language pattern, include file sed pattern); --- dependency # maker # sub MakeDepends { local(@incs); local($lang) = @_[0]; local($pattern) = @_[1]; # foreach $file (<${lang}>) { open(FILE, $file) || warn "Cannot open $file: $!\n"; while () { /$pattern/i && push(@incs, $1); } if (defined @incs) { $file =~ s/\.[^.]+$/.o/; @tab = split('/', $file); $file = '$(MODEL_LIB)(' . $tab[$#tab] . ')' ; print MAKEFILE "$file: "; &PrintWords(length($file) + 2, 0, @incs); print MAKEFILE "\n"; undef @incs; } } } # # &MakeDependsf90(f90 compiler); --- FORTRAN 90 dependency maker # sub MakeDependsf90 { local($compiler) = &toLower(@_[0]); local(@dependencies); local(%filename); local(@incs); local(@modules); local($objfile); local($DIR) = @_[1]; local($MODEL_LIB) = @_[2]; # # Associate each module with the name of the file that contains it # foreach $file (<../*/*/*.f90>) { open(FILE, $file) || warn "Cannot open $file: $!\n"; while () { /^\s*module\s+([^\s!]+)/i && ($filename{&toLower($1)} = $file) =~ s/\.f90$/.o/; } } foreach $file (<../*/*/*.F90>) { open(FILE, $file) || warn "Cannot open $file: $!\n"; while () { /^\s*module\s+([^\s!]+)/i && ($filename{&toLower($1)} = $file) =~ s/\.F90$/.o/; } } # # Print the dependencies of each file that has one or more include's or # references one or more modules # foreach $file (<../src/$DIR/*.f90 ../src/$DIR/*.F90>) { open(FILE, $file); while () { /^\s*include\s+["\']([^"\']+)["\']/i && push(@incs, $1); /^\s*use\s+([^\s,!]+)/i && push(@modules, &toLower($1)); } if (defined @incs || defined @modules) { # ($objfile = $file) =~ s/\.F90$/.o/; ($objfile = $file) =~ s/\.[fF]90$/.o/; @tab = split('/', $objfile); $objfile = '$(' . $MODEL_LIB . ')(' . $tab[$#tab] . ')' ; print MAKEFILE "$objfile: "; undef @dependencies; foreach $module (@modules) { push(@dependencies, $filename{$module}); } @dependencies = &uniq(sort(@dependencies)); foreach $dependencies (@dependencies) { @tab = split('/', $dependencies); $dependencies = '$(' . $MODEL_LIB . ')(' . $tab[$#tab] . ')'; if( "$DIR" eq 'IOSERVER' && "$dependencies" eq '$(MODEL_LIB1)(xmlio.o)' ) { $dependencies = '$(MODEL_LIB2)' # $dependencies = '' } } foreach $incs (@incs) { @tab = split('/', $incs); @incs = '../src' . '/' . $DIR. '/' . $tab[$#tab] ; } foreach $incs (@incs) { if( "$incs" eq '../src/IOSERVER/mpif.h' || "$incs" eq '../src/IOSERVER/VT.inc' || "$incs" eq '../src/IOSERVER/ios_mpif.h' ) { $incs = ''; } } &PrintWords(length($objfile) + 2, 0, @dependencies, &uniq(sort(@incs))); print MAKEFILE "\n"; undef @incs; undef @modules; # # } } }