[Numpy-svn] r4273 - in branches/numpy.scons/numpy/distutils/scons: . tests

numpy-svn@scip... numpy-svn@scip...
Tue Oct 23 06:47:56 CDT 2007


Author: cdavid
Date: 2007-10-23 06:47:46 -0500 (Tue, 23 Oct 2007)
New Revision: 4273

Added:
   branches/numpy.scons/numpy/distutils/scons/fortran.py
   branches/numpy.scons/numpy/distutils/scons/tests/
   branches/numpy.scons/numpy/distutils/scons/tests/empty.f
   branches/numpy.scons/numpy/distutils/scons/tests/fortran_output.py
   branches/numpy.scons/numpy/distutils/scons/tests/test_fortran.py
Log:

Start support of fortran and fortran-related capabilities for scons:
    * Add fortran module to parse link output of fortran compilers
    * Add test for the above functionality



Added: branches/numpy.scons/numpy/distutils/scons/fortran.py
===================================================================
--- branches/numpy.scons/numpy/distutils/scons/fortran.py	2007-10-23 10:06:59 UTC (rev 4272)
+++ branches/numpy.scons/numpy/distutils/scons/fortran.py	2007-10-23 11:47:46 UTC (rev 4273)
@@ -0,0 +1,127 @@
+#! Last Change: Tue Oct 23 08:00 PM 2007 J
+
+# This module defines some functions/classes useful for testing fortran-related
+# features (name mangling, F77/C runtime, etc...).
+
+# KEEP THIS INDEPENDENT OF SCONS, PLEASE !!!
+
+import sys
+import re
+
+GCC_DRIVER_LINE = re.compile('^Driving:')
+POSIX_STATIC_EXT = re.compile('\S+\.a')
+POSIX_LIB_FLAGS = re.compile('-l\S+')
+
+def _check_link_verbose_posix(lines):
+    """Returns true if useful link options can be found in output.
+
+    Expect lines to be a list of lines."""
+    for line in lines:
+        if not GCC_DRIVER_LINE.search(line):
+            #print line
+            #print POSIX_STATIC_EXT.search(line) 
+            #print POSIX_LIB_FLAGS.search(line)
+            if POSIX_STATIC_EXT.search(line) or POSIX_LIB_FLAGS.search(line):
+                return True
+    return False
+
+def check_link_verbose(lines):
+    if sys.platform == 'win32':
+        raise NotImplementedError("FIXME: not implemented on win32")
+    else:
+        return _check_link_verbose_posix(lines)
+
+merge_space_r1 = re.compile('^-[LRuYz]$')
+
+def merge_space(line):
+    """matcher should be a callable, line a list of tokens."""
+    nline = []
+    for i in range(len(line)):
+        ##print "hoho is %s" % line[i]
+        if merge_space_r1.match(line[i]):
+            ##print '%s matched !' % line[i]
+            merged = [line[i]]
+            if not (line[i+1][0] == '-'):
+                merged.append(line[i+1])
+                i += 1
+            nline.append(''.join(merged))
+            ##print '\t%s matched !' % ''.join(merged)
+        else:
+            nline.append(line[i])
+    return nline
+
+def homo_libpath_flags(flags):
+    nflags = []
+    #print 'flags is %s' % flags
+    #print "len flags is %d" % len(flags)
+    for i in flags:
+        if i[:4] == "-YP,":
+            i = i.replace('-YP,', '-L')
+            i = i.replace(':', ' -L')
+            nflags.append(i)
+        else:
+            nflags.append(i)
+    return nflags
+
+def parse_f77link(lines):
+    """Given the output of verbose link of F77 compiler, this returns a list of
+    flags necessary for linking using the standard linker."""
+    # TODO: On windows ?
+    # TODO: take into account quotting...
+    # TODO: those regex are really bad... Should try to get as similar as
+    # possible to autoconf here.
+    # XXX: this is really messy, clean it up !
+    ignored = ['-lang*', r'-lcrt[a-zA-Z0-9]*\.o', '-lc', '-lgcc*',
+               '-lSystem', '-libmil', '-LIST:*', '-LNO:*']
+    inter = ['-[lLR][a-zA-Z0-9]*']
+    # Those options takes an argument, so concatenate any following item
+    # until the end of the line or a new option.
+    remove_space = ['-[LRuYz]*']
+    import re
+    rignored = [re.compile(i) for i in ignored]
+    rinter = [re.compile(i) for i in inter]
+    # We ignore lines starting with Driving
+    rgccignored = re.compile('^Driving:')
+    final_flags = []
+    for line in lines:
+        # Here we go (convention for wildcard is shell, not regex !)
+        #   1 TODO: we first get some root .a libraries
+        #   2 TODO: take everything starting by -bI:*
+        #   3 TODO: ignore the following flags: -lang* | -lcrt*.o | -lc |
+        #   -lgcc* | -lSystem | -libmil | -LANG:=* | -LIST:* | -LNO:*)
+        #   4 TODO: take into account -lkernel32
+        #   5 For options of the kind -[[LRuYz]], as they take one argument
+        #   after, we have to somewhat keep it. We do as autoconf, that is
+        #   removing space between the flag and its argument.
+        #   6 For -YP,*: take and replace by -Larg where arg is the old argument
+        #   7 For -[lLR]*: take
+        if not rgccignored.match(line):
+            # Step 5
+            flags = merge_space(line.split())
+            # Step 6
+            ##print 'homo flags are: %s (%d items)' % (flags, len(flags))
+            flags = homo_libpath_flags(flags)
+            #print 'homo flags are: %s ' % flags
+            def match_ignore(str):
+                if [i for i in rignored if i.match(str)]:
+                    return True
+                else:
+                    return False
+
+            def match_interesting(str):
+                pop = [i for i in rinter if i.match(str)]
+                if pop:
+                    #print "pop %s" % str
+                    return True
+                else:
+                    return False
+
+            # Step 3
+            good_flags = [i for i in flags if not match_ignore(i)]
+            #print good_flags
+            good_flags = [i for i in good_flags if match_interesting(i)]
+            final_flags.extend(good_flags)
+    return final_flags
+
+if __name__ == '__main__':
+    pass

Added: branches/numpy.scons/numpy/distutils/scons/tests/empty.f
===================================================================
--- branches/numpy.scons/numpy/distutils/scons/tests/empty.f	2007-10-23 10:06:59 UTC (rev 4272)
+++ branches/numpy.scons/numpy/distutils/scons/tests/empty.f	2007-10-23 11:47:46 UTC (rev 4273)
@@ -0,0 +1,2 @@
+      PROGRAM HELLO
+      END

Added: branches/numpy.scons/numpy/distutils/scons/tests/fortran_output.py
===================================================================
--- branches/numpy.scons/numpy/distutils/scons/tests/fortran_output.py	2007-10-23 10:06:59 UTC (rev 4272)
+++ branches/numpy.scons/numpy/distutils/scons/tests/fortran_output.py	2007-10-23 11:47:46 UTC (rev 4273)
@@ -0,0 +1,47 @@
+# Generated bg g77 -o hello hello.o -v
+g77_link_output = """
+Driving: g77 -v empty.o -o empty -lfrtbegin -lg2c -lm -shared-libgcc
+Reading specs from /usr/lib/gcc/i486-linux-gnu/3.4.6/specs
+Configured with: ../src/configure -v --enable-languages=c,c++,f77,pascal --prefix=/usr --libexecdir=/usr/lib --with-gxx-include-dir=/usr/include/c++/3.4 --enable-shared --with-system-zlib --enable-nls --without-included-gettext --program-suffix=-3.4 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --with-tune=pentium4 i486-linux-gnu
+Thread model: posix
+gcc version 3.4.6 (Ubuntu 3.4.6-6ubuntu1)
+ /usr/lib/gcc/i486-linux-gnu/3.4.6/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o empty /usr/lib/gcc/i486-linux-gnu/3.4.6/../../../../lib/crt1.o /usr/lib/gcc/i486-linux-gnu/3.4.6/../../../../lib/crti.o /usr/lib/gcc/i486-linux-gnu/3.4.6/crtbegin.o -L/usr/lib/gcc/i486-linux-gnu/3.4.6 -L/usr/lib/gcc/i486-linux-gnu/3.4.6 -L/usr/lib/gcc/i486-linux-gnu/3.4.6/../../../../lib -L/usr/lib/gcc/i486-linux-gnu/3.4.6/../../.. -L/lib/../lib -L/usr/lib/../lib empty.o -lfrtbegin -lg2c -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/i486-linux-gnu/3.4.6/crtend.o /usr/lib/gcc/i486-linux-gnu/3.4.6/../../../../lib/crtn.o"""
+
+gfortran_link_output = """
+Driving: gfortran -v -o hello hello.o -lgfortranbegin -lgfortran -lm -shared-libgcc
+Using built-in specs.
+Target: i486-linux-gnu
+Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2 --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-targets=all --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
+Thread model: posix
+gcc version 4.2.1 (Ubuntu 4.2.1-5ubuntu4)
+ /usr/lib/gcc/i486-linux-gnu/4.2.1/collect2 --eh-frame-hdr -m elf_i386 --hash-style=both -dynamic-linker /lib/ld-linux.so.2 -o hello /usr/lib/gcc/i486-linux-gnu/4.2.1/../../../../lib/crt1.o /usr/lib/gcc/i486-linux-gnu/4.2.1/../../../../lib/crti.o /usr/lib/gcc/i486-linux-gnu/4.2.1/crtbegin.o -L/usr/lib/gcc/i486-linux-gnu/4.2.1 -L/usr/lib/gcc/i486-linux-gnu/4.2.1 -L/usr/lib/gcc/i486-linux-gnu/4.2.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/i486-linux-gnu/4.2.1/../../.. hello.o -lgfortranbegin -lgfortran -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/i486-linux-gnu/4.2.1/crtend.o /usr/lib/gcc/i486-linux-gnu/4.2.1/../../../../lib/crtn.o"""
+
+sunfort_v12_link_output = """
+NOTICE: Invoking /home/david/opt/sun/sunstudio12/bin/f90 -f77 -ftrap=%none -c empty.f
+###     command line files and options (expanded):
+    ### -f77=%all -ftrap=%none -v empty.o 
+    ### f90: Note: NLSPATH = /home/david/opt/sun/sunstudio12/prod/bin/../lib/locale/%L/LC_MESSAGES/%N.cat:/home/david/opt/sun/sunstudio12/prod/bin/../../lib/locale/%L/LC_MESSAGES/%N.cat
+    ### f90: Note: LD_LIBRARY_PATH = /home/david/local/intel/cc/9.1.042/lib:/home/david/local/lib:
+    ### f90: Note: LD_RUN_PATH     = (null)
+    ### f90: Note: LD_OPTIONS = (null)
+    /usr/bin/ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 --enable-new-dtags -R/home/david/opt/sun/sunstudio12/lib:/opt/sun/sunstudio12/lib:/home/david/opt/sun/lib/rtlibs:/opt/sun/lib/rtlibs -o a.out /home/david/opt/sun/sunstudio12/prod/lib/crti.o /home/david/opt/sun/sunstudio12/prod/lib/crt1.o /home/david/opt/sun/sunstudio12/prod/lib/values-xi.o -Y P,/home/david/opt/sun/sunstudio12/lib:/home/david/opt/sun/sunstudio12/rtlibs:/home/david/opt/sun/sunstudio12/prod/lib:/lib:/usr/lib empty.o -lfui -lfai -lfsu -Bdynamic -lmtsk -lpthread -lm -lc /home/david/opt/sun/sunstudio12/prod/lib/libc_supp.a /home/david/opt/sun/sunstudio12/prod/lib/crtn.o
+    empty.f:
+     MAIN hello:
+"""
+
+ifort_v10_link_output = """
+ld    /usr/lib/gcc/i486-linux-gnu/4.1.3/../../../crt1.o /usr/lib/gcc/i486-linux-gnu/4.1.3/../../../crti.o /usr/lib/gcc/i486-linux-gnu/4.1.3/crtbegin.o --eh-frame-hdr -dynamic-linker /lib/ld-linux.so.2 -m elf_i386 -o a.out /home/david/opt/intel/fc/10.0.023//lib/for_main.o empty.o -L/home/david/opt/intel/fc/10.0.023//lib -L/usr/lib/gcc/i486-linux-gnu/4.1.3/ -L/usr/lib/gcc/i486-linux-gnu/4.1.3/../../../ -Bstatic -lifport -lifcore -limf -Bdynamic -lm -Bstatic -lipgo -lirc -Bdynamic -lc -lgcc_s -lgcc -Bstatic -lirc_s -Bdynamic -ldl -lc /usr/lib/gcc/i486-linux-gnu/4.1.3/crtend.o /usr/lib/gcc/i486-linux-gnu/4.1.3/../../../crtn.o
+"""
+def generate_output(fcomp, verbose):
+    import os
+    os.system('%s -c %s &> /dev/null ' % (fcomp, 'empty.f'))
+    os.system('%s %s %s' % (fcomp, verbose, 'empty.o'))
+
+if __name__ == '__main__':
+    import sys
+    fcomp = sys.argv[1]
+    try:
+        vflag = sys.argv[2]
+    except IndexError:
+        vflag = '-v'
+    generate_output(fcomp, vflag)

Added: branches/numpy.scons/numpy/distutils/scons/tests/test_fortran.py
===================================================================
--- branches/numpy.scons/numpy/distutils/scons/tests/test_fortran.py	2007-10-23 10:06:59 UTC (rev 4272)
+++ branches/numpy.scons/numpy/distutils/scons/tests/test_fortran.py	2007-10-23 11:47:46 UTC (rev 4273)
@@ -0,0 +1,33 @@
+#! Last Change: Tue Oct 23 08:00 PM 2007 J
+
+import sys
+import random
+
+import unittest
+
+from fortran import parse_f77link
+
+from fortran_output import g77_link_output, gfortran_link_output, \
+        sunfort_v12_link_output, ifort_v10_link_output
+
+class TestCheckF77Verbose(unittest.TestCase):
+    def setUp(self):
+        pass
+
+    def test_g77(self):
+        print parse_f77link(g77_link_output.split('\n'))
+
+    def test_gfortran(self):
+        print parse_f77link(gfortran_link_output.split('\n'))
+
+    def test_sunf77(self):
+        print parse_f77link(sunfort_v12_link_output.split('\n'))
+
+    def test_intel_posix(self):
+        print parse_f77link(ifort_v10_link_output.split('\n'))
+
+    def test_intel_win(self):
+        print "FIXME: testing verbose output of win32 intel fortran"
+
+if __name__ == '__main__':
+    unittest.main()



More information about the Numpy-svn mailing list