From: stevenknight Date: Tue, 16 Apr 2002 10:24:10 +0000 (+0000) Subject: Handle long command lines for the MSVC linker. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=a3c5353ab89a1b195bf6cf4681ae0d488586a2db;p=scons.git Handle long command lines for the MSVC linker. git-svn-id: http://scons.tigris.org/svn/scons/trunk@333 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- diff --git a/src/CHANGES.txt b/src/CHANGES.txt index df542b9d..b14aa57a 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -64,6 +64,10 @@ RELEASE 0.07 - - Man page: Add a hierarchical libraries + Program example. + - Support long MSVC linker command lines through a builder action + that writes to a temporary file and uses the magic MSVC "link @file" + argument syntax if the line is longer than 2K characters. + From Steve Leblanc: - Add the SConscriptChdir() method. diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index 18233cf0..929dbc9a 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -134,13 +134,42 @@ Object = SCons.Builder.Builder(name = 'Object', src_suffix = static_obj.src_suffixes(), src_builder = [CFile, CXXFile]) -Program = SCons.Builder.Builder(name = 'Program', - action = '$LINKCOM', - prefix = '$PROGPREFIX', - suffix = '$PROGSUFFIX', - src_suffix = '$OBJSUFFIX', - src_builder = Object, - scanner = SCons.Scanner.Prog.ProgScan()) +def win32LinkGenerator(env, target, source, **kw): + args = [] + for a in [env['LINKFLAGS'], + '/OUT:' + str(target[0]), + env['_LIBDIRFLAGS'], + env['_LIBFLAGS'], + map(lambda x: str(x), source)]: + if SCons.Util.is_List(a): + args.extend(a) + else: + args.append(a) + argstring = string.join(args, " ") + if len(argstring) <= 2048: + return env['LINK'] + " " + argstring + else: + import tempfile + tmp = tempfile.mktemp() + open(tmp, 'w').write(argstring + "\n") + return [ env['LINK'] + " @" + tmp, + "del " + tmp, ] + +kw = { + 'name' : 'Program', + 'prefix' : '$PROGPREFIX', + 'suffix' : '$PROGSUFFIX', + 'src_suffix' : '$OBJSUFFIX', + 'src_builder' : Object, + 'scanner' : SCons.Scanner.Prog.ProgScan() +} + +if sys.platform == 'win32': + kw['generator'] = win32LinkGenerator +else: + kw['action'] = '$LINKCOM' + +Program = apply(SCons.Builder.Builder, (), kw) class LibAffixGenerator: def __init__(self, static, shared): @@ -389,7 +418,11 @@ def make_win32_env_from_paths(include, lib, path): 'SHF77PPCOM' : '$SHF77 $SHF77FLAGS $CPPFLAGS $_INCFLAGS -c -o $TARGET $SOURCES', 'LINK' : 'link', 'LINKFLAGS' : '/nologo', - 'LINKCOM' : '$LINK $LINKFLAGS /OUT:$TARGET $_LIBDIRFLAGS $_LIBFLAGS $SOURCES', + # XXX - We'd like to do this as follows, but '$LINKCOM' in + # a Builder above gets expanded too soon to stick a function + # right in the environment like this. Revisit this when this + # capability has been added (cf. bug report #537058). + #'LINKCOM' : win32Link, 'SHLINK' : '$LINK', 'SHLINKFLAGS': '$LINKFLAGS /dll', 'SHLINKCOM' : '$SHLINK $SHLINKFLAGS /OUT:$TARGET $_LIBDIRFLAGS $_LIBFLAGS $SOURCES', diff --git a/test/long-lines.py b/test/long-lines.py new file mode 100644 index 00000000..6df229cf --- /dev/null +++ b/test/long-lines.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import os +import string +import sys +import TestSCons + +test = TestSCons.TestSCons() + +if sys.platform == 'win32': + linkflag = '/LIBPATH:' + test.workpath() +else: + linkflag = '-L' + test.workpath() + +test.write('SConstruct', """ +linkflags = r'%s' +while len(linkflags) <= 8100: + linkflags = linkflags + r' %s' +env = Environment(LINKFLAGS = linkflags) +env.Program(target = 'foo', source = 'foo.c') +""" % (linkflag, linkflag)) + +test.write('foo.c', r""" +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("foo.c\n"); + exit (0); +} +""") + +test.run(arguments = '.') + +test.run(program = test.workpath('foo'), stdout = "foo.c\n") + +test.pass_test()