[MITgcm-devel] genmake2 and makedepend

Oliver Jahn jahn at MIT.EDU
Wed Dec 19 14:21:42 EST 2012


Well, this looks promising.  I am attaching a variation of the 
xmakedepend script from the tools directory that uses cpp -M.  The cpp 
used can be changed with the -cpp option (should include any arguments 
like -traditional -P).  Would have to pass this from genmake2 (and test 
for -M).

Not sure how reliable it is.  My cpp's man page says something about 
debug output being mixed in with dependency output.  The extra -M* 
options to avoid this don't seem to be portable.  I haven't seen any 
debug messages when I tried it.

I think we should still look into teaching makedepend the correct paths 
as any script along these lines will be much slower than the default 
makedepend which caches header file dependencies (cpp can only process 
one file at a time).  Seems like the "#include <...> search starts 
here:" line is pretty standard.

Oliver

On 2012-12-19 07:12, Martin Losch wrote:
> Sounds like a good idea.
>
> Here is what my exotic machines do:
> PowerBook, Mac OS X 10.8, /usr/bin/cpp seem to have the -M option (at least according to the man pages)
>>> echo | cpp -v -
> […]
> #include "..." search starts here:
> #include <...> search starts here:
>   /usr/local/include
>   /Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin11/4.2.1/include
>   /usr/include
>   /System/Library/Frameworks (framework directory)
>   /Library/Frameworks (framework directory)
> End of search list.
> […]
>
> NEC SX8 (sx8) has linux on the front end, so cpp is the linux cpp with -v and -M
>>> echo | cpp -v -
> […]
> #include "..." search starts here:
> #include <...> search starts here:
>   /usr/local/include
>   /usr/lib/gcc/ia64-suse-linux/4.1.2/include
>   /usr/lib/gcc/ia64-suse-linux/4.1.2/../../../../ia64-suse-linux/include
>   /usr/include
> End of search list.
> […]
>
> iblade >> uname -a
> AIX iblade1 3 5 0007465AD400 powerpc unknown AIX
>>> echo | /opt/freeware/bin/cpp -v -
> #include "..." search starts here:
> #include <...> search starts here:
>   /opt/freeware/include
>   /opt/freeware/lib/gcc/powerpc-ibm-aix5.3.0.0/4.2.0/include
>   /usr/include
> End of search list.
> /bin/cpp does not have -v but -M
>
> uv100:~> uname -a
> Linux uv100 3.0.13-0.27-default #1 SMP Wed Feb 15 13:33:49 UTC 2012 (d73692b) x86_64 x86_64 x86_64 GNU/Linux
> echo | /usr/cpp -v -
> #include "..." search starts here:
> #include <...> search starts here:
>   /opt/sgi/mpt/mpt-2.06/include
>   /uv/soft/intel/composer_xe_2013.1.117/composer_xe_2013.1.117/tbb/include
>   /uv/soft/intel/composer_xe_2013.1.117/composer_xe_2013.1.117/mkl/include
>   /usr/local/include
>   /usr/lib64/gcc/x86_64-suse-linux/4.3/include
>   /usr/lib64/gcc/x86_64-suse-linux/4.3/include-fixed
>   /usr/lib64/gcc/x86_64-suse-linux/4.3/../../../../x86_64-suse-linux/include
>   /usr/include
> End of search list.
> -M is also available
>
> solasrv4:~> uname -a
> SunOS solasrv4 5.10 Generic_144501-19 i86pc i386 i86pc
> cpp also seems to have -M
>>> echo | /opt/csw/bin/cpp -v -
> #include "..." search starts here:
> #include <...> search starts here:
>   /opt/csw/lib/gcc/i386-pc-solaris2.10/4.7.1/include
>   /opt/csw/include
>   /opt/csw/lib/gcc/i386-pc-solaris2.10/4.7.1/include-fixed
>   /usr/include
> End of search list.
> -M is also available
>
> On Dec 19, 2012, at 12:22 AM, Oliver Jahn <jahn at MIT.EDU> wrote:
>
>> Hi guys,
>>
>> we could also try to use cpp to generate the dependencies (possibly in the form of .d files which would make updating them more reliable). This way they would always be consistent with tests and compilation. But I don't know how standard the -M option to cpp is.  Martin, do the more exotic machines you use have it?
>>
>> Cheers,
>> Oliver
>>
>> On 2012-12-18 18:00, Jean-Michel Campin wrote:
>>> Hi Martin,
>>>
>>> I agreee that it would be good to fix this (and check that it works with
>>> our xmakedepend, with the cyrus-makedepend and with some default makedepend),
>>> but would be nicer to put the true path that cpp uses, rather than a list of
>>> potential location for the include (on my laptop, /usr/local/include
>>>   is empty but /usr/include is not).
>>> I guess the next question is, "is there a simple way to find
>>> 'the standard system include directories' ?"
>>> I can see that "cpp -v" (among many things) give a list include dirs,
>>> but don't know how standard it is (and how easy it is to extract this
>>> list).
>>>
>>> Cheers,
>>> Jean-Michel
>>>
>>> On Tue, Dec 18, 2012 at 04:36:43PM +0100, Martin Losch wrote:
>>>> Hi Jean-Michel,
>>>>
>>>> you are right, the compilation still works, it just means that the corresponding files, e.g. mmc_file.f do not depend on netcdf.inc anymore, which one can probably live with.
>>>>
>>>> I guess one can fix this by enlarging the default search for make depend, e.g. always add -I/usr/local/include (or the typical search paths of cpp) to the arguments of $(MAKEDEPEND). It's not very nice because the list is likely to expand, but should be safe, because the actual paths have been checked with the test in genmake2. What do you think?
>>>>
>>>> Martin
>>>>
>>>> On Dec 18, 2012, at 2:56 PM, Jean-Michel Campin <jmc at ocean.mit.edu> wrote:
>>>>
>>>>> Hi Martin,
>>>>>
>>>>> It happens manay times to me that "make depend" return some warning/error,
>>>>> but this does not prevent me to compile (with a successful "make").
>>>>> Are you in this situation ?
>>>>>
>>>>> Otherwise, I find your suggestion little bit tricky, since it might
>>>>> prevent to use NetCDF in cases where it is available.
>>>>> My impression is that we should try to fix the makedepend step.
>>>>>
>>>>> Cheers,
>>>>> Jean-Michel
>>>>>
>>>>> On Tue, Dec 18, 2012 at 02:04:54PM +0100, Martin Losch wrote:
>>>>>> Hi there,
>>>>>> my version of Murphy's law: Whenever you want to show how great everything is, it turns against you and does not work.
>>>>>>
>>>>>> I was trying to show to my group in a presentation, how makefiles are generated by genmake2 and how you compile the model etc, when "make depend" returned errors that it cannot find "netcdf.inc". This happened after the genmake_tnc.F test passed. I used darwin_amd64_gfortran with OS X 10.8 (mountain lion).
>>>>>>
>>>>>> The problem is that (on my PowerBook), /usr/bin/cpp finds files in /usr/local/include by default, and gfortran finds libraries in /usr/local/lib by default (that's where my netcdf installation is), so that the test passes without problems (-DHAVE_NETCDF), and more importantly without INCLUDES or INCLUDEPATH being set (I have NETCDF_ROOT unset by default). However, when make depend tries to build the dependencies, the include files are no longer found because apparently, my makedepend (/opt/X11/bin/makedepend) does not search /usr/local/include by default.
>>>>>>
>>>>>> I can easily fix this by specifying a proper NETCDF_ROOT (=/usr/local), but it shows that the netcdf test is not fool-proof. Do you have a suggestion how we can improve the test? E.g. tell cpp not to search anywhere that is not explicitly specified in the INCLUDEPATH?
>>>>>>
>>>>>> Martin
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> MITgcm-devel mailing list
>>>>>> MITgcm-devel at mitgcm.org
>>>>>> http://mitgcm.org/mailman/listinfo/mitgcm-devel
>>>>>
>>>>> _______________________________________________
>>>>> MITgcm-devel mailing list
>>>>> MITgcm-devel at mitgcm.org
>>>>> http://mitgcm.org/mailman/listinfo/mitgcm-devel
>>>>
>>>>
>>>> _______________________________________________
>>>> MITgcm-devel mailing list
>>>> MITgcm-devel at mitgcm.org
>>>> http://mitgcm.org/mailman/listinfo/mitgcm-devel
>>>
>>> _______________________________________________
>>> MITgcm-devel mailing list
>>> MITgcm-devel at mitgcm.org
>>> http://mitgcm.org/mailman/listinfo/mitgcm-devel
>>>
>>
>> _______________________________________________
>> MITgcm-devel mailing list
>> MITgcm-devel at mitgcm.org
>> http://mitgcm.org/mailman/listinfo/mitgcm-devel
>
>
> _______________________________________________
> MITgcm-devel mailing list
> MITgcm-devel at mitgcm.org
> http://mitgcm.org/mailman/listinfo/mitgcm-devel
>
-------------- next part --------------
#! /usr/bin/env sh
#
# $Header$
# $Name$
#
#	Usage:
#
#	makedepend [cpp-flags] [-s magic-string] [-f makefile]
#	  [-o object-suffix] [-cpp cpp-command]
#
#       Generate dependencies using a c preprocessor with the -M option.
#
#       The default cpp command is "cpp -traditional -P".
#
#	This script should
#	work on both USG and BSD systems.  However, when System V.4 comes out,
#	USG users will probably have to change "silent" to "-s" instead of
#	"-" (at least, that is what the documentation implies).
#

CPP="cpp -traditional -P"

silent='-'

TMP=./mdep$$
CPPCMD=${TMP}a
DEPENDLINES=${TMP}b
TMPMAKEFILE=${TMP}c
MAGICLINE=${TMP}d
ARGS=${TMP}e

trap "rm -f ${TMP}*; exit 1" 1 2 15
trap "rm -f ${TMP}*; exit 0" 1 2 13

echo " \c" > $CPPCMD
if [ `wc -c < $CPPCMD` -eq 1 ]
then
    c="\c"
    n=
else
    c=
    n="-n"
fi

echo $n "$c" >$ARGS

files=
makefile=
magic_string='# DO NOT DELETE'
objsuffix='.o'
endmarker=""
verbose=n
append=n

while [ $# != 0 ]
do
    if [ "$endmarker"x != x ] && [ "$endmarker" = "$1" ]; then
	endmarker=""
    else
	case "$1" in
	    -D*|-I*)
		echo $n " '$1'$c" >> $ARGS
		;;

	    -g|-O)	# ignore so we can just pass $(CFLAGS) in
		;;

	    *)
		if [ "$endmarker"x = x ]; then
		    case "$1" in 	
			-s)
			    magic_string="$2"
			    shift
			    ;;
			-f*)
			    if [ "$1" = "-f-" ]; then
				makefile="-"
			    else
				makefile="$2"
				shift
			    fi
			    ;;
			-o)
			    objsuffix="$2"
			    shift
			    ;;
			
			--*)
			    echo "$1" | sed 's/^\-\-//' >${TMP}end
			    endmarker="`cat ${TMP}end`"
			    rm -f ${TMP}end
			    if [ "$endmarker"x = x ]; then
				endmarker="--"
			    fi
			    ;;
			-v)
			    verbose="y"
			    ;;

			-a)
			    append="y"
			    ;;

			-cpp)
			    CPP="$2"
			    shift
			    ;;

			-*)
			    echo "Unknown option '$1' ignored" 1>&2
			    ;;
			*)
			    files="$files $1"
			    ;;
		    esac
		fi
		;;
	esac
    fi
    shift
done
echo ' $*' >> $ARGS

echo "#!/bin/sh" > $CPPCMD
echo "exec $CPP -M `cat $ARGS`" >> $CPPCMD
chmod +x $CPPCMD
rm $ARGS

case "$makefile" in
    '')
	if [ -r makefile ]
	then
	    makefile=makefile
	elif [ -r Makefile ]
	then
	    makefile=Makefile
	else
	    echo 'no makefile or Makefile found' 1>&2
	    exit 1
	fi
	;;
    -)
	makefile=$TMPMAKEFILE
	;;
esac

if [ "$verbose"x = "y"x ]; then
    cat $CPP
fi

echo '' > $DEPENDLINES
for i in $files
do
    # replace .o by objsuffix and get rid of .F dependency
    $CPPCMD $i | sed -e "s|\.o *:|$objsuffix:|" -e 's| [^[:space:]]*.F | |' >> $DEPENDLINES
done

trap "" 1 2 13 15	# Now we are committed
case "$makefile" in
    $TMPMAKEFILE)
	;;
    *)
	rm -f $makefile.bak
	cp $makefile $makefile.bak
	echo "Appending dependencies to $makefile"
	;;
esac

#
# If not -a, append the magic string and a blank line so that
# /^$magic_string/+1,\$d can be used to delete everything from after
# the magic string to the end of the file.  Then, append a blank
# line again and then the dependencies.
#
if [ "$append" = "n" ]
then
    cat >> $makefile << END_OF_APPEND

$magic_string

END_OF_APPEND
    ed $silent $makefile << END_OF_ED_SCRIPT
/^$magic_string/+1,\$d
w
q
END_OF_ED_SCRIPT
    echo '' >>$makefile
fi

cat $DEPENDLINES >>$makefile

case "$makefile" in
    $TMPMAKEFILE)
	cat $TMPMAKEFILE
	;;
esac

rm -f ${TMP}*
exit 0


More information about the MITgcm-devel mailing list