Support arbitrary header-file preambles when checking for #include files.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 21 Oct 2003 03:52:32 +0000 (03:52 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 21 Oct 2003 03:52:32 +0000 (03:52 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@822 fdb21ef1-2011-0410-befe-b5e4ea1792b1

doc/man/scons.1
src/CHANGES.txt
src/engine/SCons/SConf.py
src/engine/SCons/SConfTests.py

index 9b11f6bee3983c7882868519848366801c09e851..0c98c11f585df804d521912f5bf870de10143c39 100644 (file)
@@ -5112,6 +5112,15 @@ goes by and developers contribute new useful tests.)
 Checks if 
 .I header
 is usable in the specified language.
+.I header
+may be a list,
+in which case the last item in the list
+is the header file to be checked,
+and the previous list items are
+header files whose
+.B #include
+lines should precede the
+header line being checked for.
 The optional argument 
 .I include_quotes 
 must be
@@ -5133,7 +5142,17 @@ This is a wrapper around
 .B Configure.CheckHeader
 which checks if 
 .I header
-is usable in the C language. The optional argument 
+is usable in the C language.
+.I header
+may be a list,
+in which case the last item in the list
+is the header file to be checked,
+and the previous list items are
+header files whose
+.B #include
+lines should precede the
+header line being checked for.
+The optional argument 
 .I include_quotes 
 must be
 a two character string, where the first character denotes the opening
@@ -5147,7 +5166,17 @@ This is a wrapper around
 .B Configure.CheckHeader
 which checks if 
 .I header
-is usable in the C++ language. The optional argument 
+is usable in the C++ language.
+.I header
+may be a list,
+in which case the last item in the list
+is the header file to be checked,
+and the previous list items are
+header files whose
+.B #include
+lines should precede the
+header line being checked for.
+The optional argument 
 .I include_quotes 
 must be
 a two character string, where the first character denotes the opening
@@ -5217,6 +5246,15 @@ Again,
 specifies the library to check. 
 .I header
 specifies a header to check for.
+.I header
+may be a list,
+in which case the last item in the list
+is the header file to be checked,
+and the previous list items are
+header files whose
+.B #include
+lines should precede the
+header line being checked for.
 .I language
 may be one of 'C','c','CXX','cxx','C++' and 'c++'.
 .I call
index 6e81a3e330793b022a030277f6dc14b9abeb2e5a..f83f35418a8a88094cd93f4f91b281020813d2a8 100644 (file)
@@ -126,6 +126,12 @@ RELEASE X.XX - XXX
   - Fix ParseConfig() so it works regardless of initial construction
     variable values.
 
+    Extend CheckHeader(), CheckCHeader(), CheckCXXHeader() and
+    CheckLibWithHeader() to accept a list of header files that will be
+    #included in the test.  The last one in the list is assumed to be
+    the one being checked for.  (Prototype code contributed by Gerard
+    Patel and Niall Douglas).
+
   From Clark McGrew:
 
   - Generalize the action for .tex files so that it will decide whether
index ee3a6b520e4b2dc9ace6838e87d9ffeb3a92d6b0..0fbde14c5504c3fe96e85642eed3550d36cd0ccf 100644 (file)
@@ -30,6 +30,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import cPickle
 import os
+import string
 import sys
 import traceback
 from types import *
@@ -109,6 +110,7 @@ class SConf:
         default_tests = {
                  'CheckFunc'          : CheckFunc,
                  'CheckType'          : CheckType,
+                 'CheckHeader'        : CheckHeader,
                  'CheckCHeader'       : CheckCHeader,
                  'CheckCXXHeader'     : CheckCXXHeader,
                  'CheckLib'           : CheckLib,
@@ -643,9 +645,14 @@ def CheckHeader(context, header, include_quotes = '<>', language = None):
     """
     A test for a C or C++ header file.
     """
-    # ToDo: Support also system header files (i.e. #include <header.h>)
-    res = SCons.Conftest.CheckHeader(context, header, language = language,
-                                               include_quotes = include_quotes)
+    if not SCons.Util.is_List(header):
+        header = [header]
+    l = []
+    for s in header[:-1]:
+        l.append("#include %s%s%s\n" % (include_quotes[0], s, include_quotes[1]))
+    res = SCons.Conftest.CheckHeader(context, header[-1], string.join(l, ''),
+                                     language = language,
+                                     include_quotes = include_quotes)
     context.did_show_result = 1
     if not res:
         return 1        # Ok
@@ -700,8 +707,13 @@ def CheckLibWithHeader(context, library, header, language,
     without extra link flags.
     """
 
-    res = SCons.Conftest.CheckLib(context, library, "main",
-            header = '#include "%s"' % header,
+    if not SCons.Util.is_List(header):
+        header = [header]
+    l = []
+    for s in header:
+        l.append('#include "%s"\n' % (s))
+
+    res = SCons.Conftest.CheckLib(context, library, "main", string.join(l, ''),
             call = call, language = language, autoadd = autoadd)
     context.did_show_result = 1
     if not res:
index 3240aa41bd18adb591579c1a50afd22122857237..78b27bd3e03df65ee768c04dc903a9567bba0d8b 100644 (file)
@@ -259,91 +259,107 @@ int main() {
     def test_StandardTests(self):
         """Test standard checks
         """
-        def CHeaderChecks( sconf ):
-            res1 = sconf.CheckCHeader( "stdio.h", include_quotes="<>" )
-            res2 = sconf.CheckCHeader( "HopefullyNotCHeader.noh" )
-            return (res1,res2)
+        self._resetSConfState()
+        sconf = self.SConf.SConf(self.scons_env,
+                                 conf_dir=self.test.workpath('config.tests'),
+                                 log_file=self.test.workpath('config.log'))
+        try:
+            # CheckHeader()
+            r = sconf.CheckHeader( "stdio.h", include_quotes="<>", language="C" )
+            assert r, "did not find stdio.h"
+            r = sconf.CheckHeader( "HopefullyNoHeader.noh", language="C" )
+            assert not r, "unexpectedly found HopefullyNoHeader.noh"
+            r = sconf.CheckHeader( "vector", include_quotes="<>", language="C++" )
+            assert r, "did not find vector"
+            r = sconf.CheckHeader( "HopefullyNoHeader.noh", language="C++" )
+            assert not r, "unexpectedly found HopefullyNoHeader.noh"
 
-        def CXXHeaderChecks(sconf):
-            res1 = sconf.CheckCXXHeader( "vector", include_quotes="<>" )
-            res2 = sconf.CheckCXXHeader( "HopefullyNotCXXHeader.noh" )
-            return (res1,res2)
+            # CheckCHeader()
+            r = sconf.CheckCHeader( "stdio.h", include_quotes="<>" )
+            assert r, "did not find stdio.h"
+            r = sconf.CheckCHeader( ["math.h", "stdio.h"], include_quotes="<>" )
+            assert r, "did not find stdio.h, #include math.h first"
+            r = sconf.CheckCHeader( "HopefullyNoCHeader.noh" )
+            assert not r, "unexpectedly found HopefullyNoCHeader.noh"
 
-        def LibChecks(sconf):
-            res1 = sconf.CheckLib( existing_lib, "main", autoadd=0 )
-            res2 = sconf.CheckLib( "hopefullynolib", "main", autoadd=0 )
-            return (res1, res2)
-        
-        def LibChecksAutoAdd(sconf):
+            # CheckCXXHeader()
+            r = sconf.CheckCXXHeader( "vector", include_quotes="<>" )
+            assert r, "did not find vector"
+            r = sconf.CheckCXXHeader( ["stdio.h", "vector"], include_quotes="<>" )
+            assert r, "did not find vector, #include stdio.h first"
+            r = sconf.CheckCXXHeader( "HopefullyNoCXXHeader.noh" )
+            assert not r, "unexpectedly found HopefullyNoCXXHeader.noh"
+
+            # CheckLib()
+            r = sconf.CheckLib( existing_lib, "main", autoadd=0 )
+            assert r, "did not find %s" % existing_lib
+            r = sconf.CheckLib( "hopefullynolib", "main", autoadd=0 )
+            assert not r, "unexpectedly found hopefullynolib"
+
+            # CheckLib() with autoadd
             def libs(env):
-                if env.has_key( "LIBS" ):
-                    return env['LIBS']
-                else:
-                    return []
+                return env.get('LIBS', [])
+
             env = sconf.env.Copy()
-            res1 = sconf.CheckLib( existing_lib, "main", autoadd=1 )
-            libs1 = (libs(env), libs(sconf.env) )
-            sconf.env = env.Copy()
-            res2 = sconf.CheckLib( existing_lib, "main", autoadd=0 )
-            libs2 = (libs(env), libs(sconf.env) )
-            sconf.env = env.Copy()
-            return ((res1, libs1), (res2, libs2))
-
-        def LibWithHeaderChecks(sconf):
-            res1 = sconf.CheckLibWithHeader( existing_lib, "math.h", "C", autoadd=0 )
-            res2 = sconf.CheckLibWithHeader( "hopefullynolib", "math.h", "C", autoadd=0 )
-            return (res1, res2)
 
-        def LibWithHeaderChecksAutoAdd(sconf):
+            try:
+                r = sconf.CheckLib( existing_lib, "main", autoadd=1 )
+                assert r, "did not find main in %s" % existing_lib
+                expect = libs(env) + [existing_lib]
+                got = libs(sconf.env)
+                assert got == expect, "LIBS: expected %s, got %s" % (expect, got)
+
+                sconf.env = env.Copy()
+                r = sconf.CheckLib( existing_lib, "main", autoadd=0 )
+                assert r, "did not find main in %s" % existing_lib
+                expect = libs(env)
+                got = libs(sconf.env)
+                assert got == expect, "before and after LIBS were not the same"
+            finally:
+                sconf.env = env
+
+            # CheckLibWithHeader()
+            r = sconf.CheckLibWithHeader( existing_lib, "math.h", "C", autoadd=0 )
+            assert r, "did not find %s" % existing_lib
+            r = sconf.CheckLibWithHeader( existing_lib, ["stdio.h", "math.h"], "C", autoadd=0 )
+            assert r, "did not find %s, #include stdio.h first" % existing_lib
+            r = sconf.CheckLibWithHeader( "hopefullynolib", "math.h", "C", autoadd=0 )
+            assert not r, "unexpectedly found hopefullynolib"
+
+            # CheckLibWithHeader with autoadd
             def libs(env):
-                if env.has_key( "LIBS" ):
-                    return env['LIBS']
-                else:
-                    return []
+                return env.get('LIBS', [])
+
             env = sconf.env.Copy()
-            res1 = sconf.CheckLibWithHeader( existing_lib, "math.h", "C", autoadd=1 )
-            libs1 = (libs(env), libs(sconf.env) )
-            sconf.env = env.Copy()
-            res2 = sconf.CheckLibWithHeader( existing_lib, "math.h", "C", autoadd=0 )
-            libs2 = (libs(env), libs(sconf.env) )
-            sconf.env = env.Copy()
-            return ((res1, libs1), (res2, libs2))
-
-        def FuncChecks(sconf):
-            res1 = sconf.CheckFunc('strcpy')
-            res2 = sconf.CheckFunc('hopefullynofunction')
-            return (res1, res2)
 
-        def TypeChecks(sconf):
-            res1 = sconf.CheckType('off_t', '#include <sys/types.h>\n')
-            res2 = sconf.CheckType('hopefullynotypedef_not')
-            return (res1, res2)
+            try:
+                r = sconf.CheckLibWithHeader( existing_lib, "math.h", "C", autoadd=1 )
+                assert r, "did not find math.h with %s" % existing_lib
+                expect = libs(env) + [existing_lib]
+                got = libs(sconf.env)
+                assert got == expect, "LIBS: expected %s, got %s" % (expect, got)
+
+                sconf.env = env.Copy()
+                r = sconf.CheckLibWithHeader( existing_lib, "math.h", "C", autoadd=0 )
+                assert r, "did not find math.h with %s" % existing_lib
+                expect = libs(env)
+                got = libs(sconf.env)
+                assert got == expect, "before and after LIBS were not the same"
+            finally:
+                sconf.env = env
+
+            # CheckFunc()
+            r = sconf.CheckFunc('strcpy')
+            assert r, "did not find strcpy"
+            r = sconf.CheckFunc('hopefullynofunction')
+            assert not r, "unexpectedly found hopefullynofunction"
+
+            # CheckType()
+            r = sconf.CheckType('off_t', '#include <sys/types.h>\n')
+            assert r, "did not find off_t"
+            r = sconf.CheckType('hopefullynotypedef_not')
+            assert not r, "unexpectedly found hopefullynotypedef_not"
 
-        self._resetSConfState()
-        sconf = self.SConf.SConf(self.scons_env,
-                                 conf_dir=self.test.workpath('config.tests'),
-                                 log_file=self.test.workpath('config.log'))
-        try:
-            (res1, res2) = CHeaderChecks(sconf)
-            assert res1 and not res2 
-            (res1, res2) = CXXHeaderChecks(sconf)
-            assert res1 and not res2 
-            (res1, res2) = LibChecks(sconf)
-            assert res1 and not res2 
-            ((res1, libs1), (res2, libs2)) = LibChecksAutoAdd(sconf)
-            assert res1 and res2 
-            assert len(libs1[1]) - 1 == len(libs1[0]) and libs1[1][-1] == existing_lib
-            assert len(libs2[1]) == len(libs2[0]) 
-            (res1, res2) = LibWithHeaderChecks(sconf)
-            assert res1 and not res2 
-            ((res1, libs1), (res2, libs2)) = LibWithHeaderChecksAutoAdd(sconf)
-            assert res1 and res2 
-            assert len(libs1[1]) - 1 == len(libs1[0]) and libs1[1][-1] == existing_lib
-            assert len(libs2[1]) == len(libs2[0]) 
-            (res1, res2) = FuncChecks(sconf)
-            assert res1 and not res2 
-            (res1, res2) = TypeChecks(sconf)
-            assert res1 and not res2 
         finally:
             sconf.Finish()