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

numpy-svn@scip... numpy-svn@scip...
Fri Oct 26 03:06:59 CDT 2007


Author: cdavid
Date: 2007-10-26 03:06:46 -0500 (Fri, 26 Oct 2007)
New Revision: 4305

Modified:
   branches/numpy.scons/numpy/distutils/scons/__init__.py
   branches/numpy.scons/numpy/distutils/scons/fortran.py
   branches/numpy.scons/numpy/distutils/scons/tests/fortran_output.py
   branches/numpy.scons/numpy/distutils/scons/tests/test_fortran.py
Log:
Refactor fortran link output parsing + tests

Modified: branches/numpy.scons/numpy/distutils/scons/__init__.py
===================================================================
--- branches/numpy.scons/numpy/distutils/scons/__init__.py	2007-10-26 07:18:53 UTC (rev 4304)
+++ branches/numpy.scons/numpy/distutils/scons/__init__.py	2007-10-26 08:06:46 UTC (rev 4305)
@@ -5,6 +5,7 @@
         CheckAccelerate, CheckMKL, CheckSunperf
 from extension import get_python_inc, get_pythonlib_dir
 from utils import isstring
+import fortran
 
 def test(level=1, verbosity=1):
     from numpy.testing import NumpyTest

Modified: branches/numpy.scons/numpy/distutils/scons/fortran.py
===================================================================
--- branches/numpy.scons/numpy/distutils/scons/fortran.py	2007-10-26 07:18:53 UTC (rev 4304)
+++ branches/numpy.scons/numpy/distutils/scons/fortran.py	2007-10-26 08:06:46 UTC (rev 4305)
@@ -1,10 +1,9 @@
-#! Last Change: Fri Oct 26 03:00 PM 2007 J
+#! Last Change: Fri Oct 26 04: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 !!!
-# All this module is total crap, refactor it + needs testing
 
 import sys
 import re
@@ -14,81 +13,89 @@
 POSIX_LIB_FLAGS = re.compile('-l\S+')
 MERGE_SPACE_R1 = re.compile('^-[LRuYz]$')
 
+# linkflags which match those are ignored
+LINKFLAGS_IGNORED = [r'-lang*', r'-lcrt[a-zA-Z0-9]*\.o', r'-lc', r'-lgcc*',
+                     r'-lSystem', r'-libmil', r'-LIST:*', r'-LNO:*']
+RLINKFLAGS_IGNORED = [re.compile(i) for i in LINKFLAGS_IGNORED]
 
+# linkflags which match those are the one we are interested in
+LINKFLAGS_INTERESTING = [r'-[lLR][a-zA-Z0-9]*']
+RLINKFLAGS_INTERESTING = [re.compile(i) for i in LINKFLAGS_INTERESTING]
+
 def _check_link_verbose_posix(lines):
     """Returns true if useful link options can be found in output.
 
+    POSIX implementation.
+
     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):
+    """Return true if useful link option can be found in output."""
     if sys.platform == 'win32':
         raise NotImplementedError("FIXME: not implemented on win32")
     else:
         return _check_link_verbose_posix(lines)
 
 def merge_space(line):
-    """matcher should be a callable, line a list of tokens."""
+    """For options taking an argument, merge them to avoid spaces.
+    
+    line should be 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):
+    """For arguments like -YP, transform them into -L."""
     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)
+            nflags.extend(i.split(' '))
         else:
             nflags.append(i)
     return nflags
 
+def match_ignore(str):
+    if [i for i in RLINKFLAGS_IGNORED if i.match(str)]:
+        return True
+    else:
+        return False
+
+def match_interesting(str):
+    pop = [i for i in RLINKFLAGS_INTERESTING if i.match(str)]
+    if pop:
+        return True
+    else:
+        return False
+
 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 |
+        #   3 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
@@ -96,31 +103,21 @@
         #   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):
+        if not GCC_DRIVER_LINE.match(line):
+            flags = line.split()
+
+            # Step 3
+            flags = [i for i in flags if not match_ignore(i)]
+
             # Step 5
-            flags = merge_space(line.split())
+            flags = merge_space(flags)
+
             # 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 7
+            good_flags = [i for i in flags if match_interesting(i)]
 
-            # 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
 

Modified: branches/numpy.scons/numpy/distutils/scons/tests/fortran_output.py
===================================================================
--- branches/numpy.scons/numpy/distutils/scons/tests/fortran_output.py	2007-10-26 07:18:53 UTC (rev 4304)
+++ branches/numpy.scons/numpy/distutils/scons/tests/fortran_output.py	2007-10-26 08:06:46 UTC (rev 4305)
@@ -7,6 +7,12 @@
 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"""
 
+g77_link_expected = ['-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', '-lfrtbegin', '-lg2c', '-lm']
+
 gfortran_link_output = """
 Driving: gfortran -v -o hello hello.o -lgfortranbegin -lgfortran -lm -shared-libgcc
 Using built-in specs.
@@ -16,6 +22,12 @@
 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"""
 
+gfortran_link_expected = ['-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/../../..',
+        '-lgfortranbegin', '-lgfortran', '-lm']
+
 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):
@@ -29,9 +41,22 @@
      MAIN hello:
 """
 
+sunfort_v12_link_expected = ['-R/home/david/opt/sun/sunstudio12/lib:'\
+        '/opt/sun/sunstudio12/lib:/home/david/opt/sun/lib/rtlibs:'\
+        '/opt/sun/lib/rtlibs', '-L/home/david/opt/sun/sunstudio12/lib',
+        '-L/home/david/opt/sun/sunstudio12/rtlibs',
+        '-L/home/david/opt/sun/sunstudio12/prod/lib', '-L/lib', '-L/usr/lib',
+        '-lfui', '-lfai', '-lfsu', '-lmtsk', '-lpthread', '-lm']
+
 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
 """
+
+ifort_v10_link_expected = ['-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/../../../', '-lifport',
+        '-lifcore', '-limf', '-lm', '-lipgo', '-lirc', '-lirc_s', '-ldl']
+
 def generate_output(fcomp, verbose):
     import os
     os.system('%s -c %s &> /dev/null ' % (fcomp, 'empty.f'))

Modified: branches/numpy.scons/numpy/distutils/scons/tests/test_fortran.py
===================================================================
--- branches/numpy.scons/numpy/distutils/scons/tests/test_fortran.py	2007-10-26 07:18:53 UTC (rev 4304)
+++ branches/numpy.scons/numpy/distutils/scons/tests/test_fortran.py	2007-10-26 08:06:46 UTC (rev 4305)
@@ -1,33 +1,45 @@
-#! Last Change: Tue Oct 23 08:00 PM 2007 J
+#! Last Change: Fri Oct 26 04:00 PM 2007 J
 
-import sys
-import random
+from numpy.testing import NumpyTestCase, set_package_path, restore_path, set_local_path
 
-import unittest
+set_package_path()
+from scons.fortran import parse_f77link
+restore_path()
 
-from fortran import parse_f77link
-
+set_local_path()
 from fortran_output import g77_link_output, gfortran_link_output, \
-        sunfort_v12_link_output, ifort_v10_link_output
+        sunfort_v12_link_output, ifort_v10_link_output, \
+        g77_link_expected, gfortran_link_expected, \
+        sunfort_v12_link_expected, ifort_v10_link_expected
+restore_path()
 
-class TestCheckF77Verbose(unittest.TestCase):
+class test_CheckF77Verbose(NumpyTestCase):
     def setUp(self):
         pass
 
     def test_g77(self):
-        print parse_f77link(g77_link_output.split('\n'))
+        """Parsing g77 link output."""
+        assert parse_f77link(g77_link_output.split('\n')) == g77_link_expected
 
     def test_gfortran(self):
-        print parse_f77link(gfortran_link_output.split('\n'))
+        """Parsing gfortran link output."""
+        assert parse_f77link(gfortran_link_output.split('\n')) == \
+               gfortran_link_expected
 
     def test_sunf77(self):
-        print parse_f77link(sunfort_v12_link_output.split('\n'))
+        """Parsing sunfort link output."""
+        assert parse_f77link(sunfort_v12_link_output.split('\n')) == \
+               sunfort_v12_link_expected
 
     def test_intel_posix(self):
-        print parse_f77link(ifort_v10_link_output.split('\n'))
+        """Parsing ifort link output."""
+        assert parse_f77link(ifort_v10_link_output.split('\n')) == \
+               ifort_v10_link_expected
 
     def test_intel_win(self):
+        """Parsing ifort link output on win32."""
         print "FIXME: testing verbose output of win32 intel fortran"
 
 if __name__ == '__main__':
-    unittest.main()
+    from numpy.testing import NumpyTest
+    NumpyTest().test()



More information about the Numpy-svn mailing list