Extend Win32 long command-line processing to lib.py. (Matt Balvin)
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 30 Nov 2002 22:28:19 +0000 (22:28 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 30 Nov 2002 22:28:19 +0000 (22:28 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@511 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/Platform/win32.py
src/engine/SCons/Tool/lib.py
src/engine/SCons/Tool/mslink.py
test/long-lines.py

index 626db729905eafc26a6eeffd553659e6cb174d23..586f81a2372209005bc64703548534f3f2bc8c2f 100644 (file)
@@ -23,6 +23,11 @@ RELEASE 0.09 -
 
   - Support file names with odd characters in them.
 
+ From Matt Balvin:
+
+ - Add long command-line support to the "lib" (MicroSoft static library)
+   Tool, too.
+
  From Steven Knight:
 
  - Fix auto-deduction of target names so that deduced targets end
index b54aefe6d1de7babf6331c4edfe16b83828c3063..db601e15492a79c53c975442c477c0c4c5d52a70 100644 (file)
@@ -38,6 +38,30 @@ import os.path
 import string
 import sys
 
+#
+
+def TempFileMunge(env, cmd_list, for_signature): 
+    """Given a list of command line arguments, see if it is too
+    long to pass to the win32 command line interpreter.  If so,
+    create a temp file, then pass "@tempfile" as the sole argument
+    to the supplied command (which is the first element of cmd_list).
+    Otherwise, just return [cmd_list]."""
+    cmd = env.subst_list(cmd_list)[0]
+    if for_signature or \
+       (reduce(lambda x, y: x + len(y), cmd, 0) + len(cmd)) <= 2048:
+        return [cmd_list]
+    else:
+        import tempfile
+        # We do a normpath because mktemp() has what appears to be
+        # a bug in Win32 that will use a forward slash as a path
+        # delimiter.  Win32's link mistakes that for a command line
+        # switch and barfs.
+        tmp = os.path.normpath(tempfile.mktemp())
+        args = map(SCons.Util.quote_spaces, cmd[1:])
+        open(tmp, 'w').write(string.join(args, " ") + "\n")
+        return [ [cmd[0], '@' + tmp],
+                 ['del', tmp] ]
+
 # The upshot of all this is that, if you are using Python 1.5.2,
 # you had better have cmd or command.com in your PATH when you run
 # scons.
index d1b3bf00c9f0366374d852644051f40609787df4..ed93bb98e7bea70e9e1f5f7b29cbfac94d762e70 100644 (file)
@@ -35,6 +35,15 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import SCons.Defaults
 
+from SCons.Platform.win32 import TempFileMunge
+
+def win32ArGenerator(env, target, source, for_signature, **kw):
+    args = [ '$AR', '$ARFLAGS', '/OUT:%s' % target[0]]
+    args.extend(map(SCons.Util.to_String, source))
+    return TempFileMunge(env, args, for_signature)
+
+ArAction = SCons.Action.CommandGenerator(win32ArGenerator)
+
 def generate(env, platform):
     """Add Builders and construction variables for lib to an Environment."""
     env['BUILDERS']['Library'] = SCons.Defaults.StaticLibrary
@@ -42,7 +51,7 @@ def generate(env, platform):
     
     env['AR']          = 'lib'
     env['ARFLAGS']     = '/nologo'
-    env['ARCOM']       = '$AR $ARFLAGS /OUT:$TARGET $SOURCES'
+    env['ARCOM']       = ArAction
 
 def exists(env):
     return env.Detect('lib')
index 79bf1d86aab34008abd68c387e142eedef0ac078..133e700b45c63cf4a738ff8f4b238a1ef97c4292 100644 (file)
@@ -36,35 +36,14 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import os.path
 import string
 
+import SCons.Action
 import SCons.Defaults
 import SCons.Errors
-import SCons.Action
 import SCons.Util
 import msvc
 
+from SCons.Platform.win32 import TempFileMunge
 from SCons.Tool.msvc import get_msdev_paths
-
-def win32TempFileMunge(env, cmd_list, for_signature): 
-    """Given a list of command line arguments, see if it is too
-    long to pass to the win32 command line interpreter.  If so,
-    create a temp file, then pass "@tempfile" as the sole argument
-    to the supplied command (which is the first element of cmd_list).
-    Otherwise, just return [cmd_list]."""
-    cmd = env.subst_list(cmd_list)[0]
-    if for_signature or \
-       (reduce(lambda x, y: x + len(y), cmd, 0) + len(cmd)) <= 2048:
-        return [cmd_list]
-    else:
-        import tempfile
-        # We do a normpath because mktemp() has what appears to be
-        # a bug in Win32 that will use a forward slash as a path
-        # delimiter.  Win32's link mistakes that for a command line
-        # switch and barfs.
-        tmp = os.path.normpath(tempfile.mktemp())
-        args = map(SCons.Util.quote_spaces, cmd[1:])
-        open(tmp, 'w').write(string.join(args, " ") + "\n")
-        return [ [cmd[0], '@' + tmp],
-                 ['del', tmp] ]
     
 def win32LinkGenerator(env, target, source, for_signature):
     args = [ '$LINK', '$LINKFLAGS', '/OUT:%s' % target[0],
@@ -74,7 +53,7 @@ def win32LinkGenerator(env, target, source, for_signature):
         args.extend(['/PDB:%s'%target[0].File(env['PDB']), '/DEBUG'])
 
     args.extend(map(SCons.Util.to_String, source))
-    return win32TempFileMunge(env, args, for_signature)
+    return TempFileMunge(env, args, for_signature)
 
 def win32LibGenerator(target, source, env, for_signature):
     listCmd = [ "$SHLINK", "$SHLINKFLAGS" ]
@@ -103,7 +82,7 @@ def win32LibGenerator(target, source, env, for_signature):
             # Just treat it as a generic source file.
             listCmd.append(str(src))
 
-    return win32TempFileMunge(env, listCmd, for_signature)
+    return TempFileMunge(env, listCmd, for_signature)
 
 def win32LibEmitter(target, source, env):
     msvc.validate_vars(env)
index f2dc9fc3048d037ca296d0713cc929cea5991fee..a3765ca5884b2dc123ee97059a0f547a5dba15b5 100644 (file)
@@ -33,23 +33,37 @@ import TestSCons
 test = TestSCons.TestSCons()
 
 if sys.platform == 'win32':
-    lib_=''
-    _dll = '.dll'
-    linkflag = '/LIBPATH:' + test.workpath()
+    lib_static_lib = 'static.lib'
+    lib_shared_dll ='shared.dll'
+    arflag_init = '/LIBPATH:' + test.workpath()
+    arflag = ' /LIBPATH:' + test.workpath()
+    linkflag_init = '/LIBPATH:' + test.workpath()
+    linkflag = ' /LIBPATH:' + test.workpath()
 else:
-    lib_='lib'
-    _dll='.so'
-    linkflag = '-L' + test.workpath()
+    lib_shared_dll = 'libshared.so'
+    lib_static_lib = 'libstatic.a'
+    arflag_init = 'r'
+    arflag = 'o'
+    linkflag_init = '-L' + test.workpath()
+    linkflag = ' -L' + test.workpath()
 
 test.write('SConstruct', """
+arflags = r'%s'
+while len(arflags) <= 8100:
+    arflags = arflags + r'%s'
+
 linkflags = r'%s'
 while len(linkflags) <= 8100:
-    linkflags = linkflags + r' %s'
-env = Environment(LINKFLAGS = '$LINKXXX', LINKXXX = linkflags)
+    linkflags = linkflags + r'%s'
+
+env = Environment(ARFLAGS = '$ARXXX', ARXXX = arflags,
+                  LINKFLAGS = '$LINKXXX', LINKXXX = linkflags)
 env.Program(target = 'foo', source = 'foo.c')
+
+env.StaticLibrary(target = 'static', source = 'static.c')
 # SharedLibrary() uses $LINKFLAGS by default.
-env.SharedLibrary(target = 'bar', source = 'bar.c', no_import_lib=1)
-""" % (linkflag, linkflag))
+env.SharedLibrary(target = 'shared', source = 'shared.c', no_import_lib=1)
+""" % (arflag_init, arflag, linkflag_init, linkflag))
 
 test.write('foo.c', r"""
 int
@@ -61,12 +75,22 @@ main(int argc, char *argv[])
 }
 """)
 
-test.write('bar.c', r"""
+test.write('static.c', r"""
 int
 main(int argc, char *argv[])
 {
        argv[argc++] = "--";
-       printf("foo.c\n");
+       printf("static.c\n");
+       exit (0);
+}
+""")
+
+test.write('shared.c', r"""
+int
+main(int argc, char *argv[])
+{
+       argv[argc++] = "--";
+       printf("shared.c\n");
        exit (0);
 }
 """)
@@ -78,6 +102,8 @@ test.up_to_date(arguments = '.')
 
 test.run(program = test.workpath('foo'), stdout = "foo.c\n")
 
-test.fail_test(not os.path.exists(lib_+'bar'+_dll))
+test.fail_test(not os.path.exists(lib_static_lib))
+
+test.fail_test(not os.path.exists(lib_shared_dll))
 
 test.pass_test()