[Scons-users] Using $SOURCE files with _concat and Command String Parsing

Christopher Murray murpup at gmail.com
Mon Aug 26 23:26:02 EDT 2013


This may not help entirely, but it may create the spark needed to push
through the issue. I did not attempt to parse in depth everything you
said, but you seem to be experiencing issues not entirely dissimilar to
what I ran into years ago when I was trying to get our mixed Fortran/C code
to compile under Cygwin using its native Python but using the Windows-based
MSVS/Intel Fortran tool chain. I had issues with getting the concatenation
process to work as needed. What I ended up doing was to define my own
concatenation routine and use it wherever _concat was not doing the job,
like this:


import build_utils # my own custom library of support functions

# Define our own concatenation routine so that path names can be
# permuted to use win32 path separators. It is in build_support.py
env['cvf_concat'] = build_utils.cvf_concat
env['_F90INCFLAGS'] = '${cvf_concat(INCPREFIX, F90PATH, INCSUFFIX, __env__,
RDirs)}'


Then in build_utils.py, there is the following (which, if I remember
correctly, is just a modified version of _concat):


from SCons.Subst import *
from SCons.PathList import *

# Redefine my own concatenation routine so that path names are treated
# correctly under cygwin.
def cvf_concat(prefix, list, suffix, env, f=lambda x: x, target=None,
source=None):
"""Creates a new list from 'list' by first interpolating each
element in the list using the 'env' dictionary and then calling f
on the list, and finally concatenating 'prefix' and 'suffix' onto
each element of the list. A trailing space on 'prefix' or leading
space on 'suffix' will cause them to be put into separate list
elements rather than being concatenated."""

if not list:
return prefix

l = f(SCons.PathList.PathList(list).subst_path(env, target, source))

if l is not None:
list = l

result = []

# ensure that prefix and suffix are strings
prefix = str(env.subst(prefix, SCons.Subst.SUBST_RAW))
suffix = str(env.subst(suffix, SCons.Subst.SUBST_RAW))

for x in list:
if isinstance(x, SCons.Node.FS.File):
result.append(x)
continue
x = str(x)
x = PermutePath(x, "\\\\")
if x:
if prefix:
if prefix[-1] == ' ':
result.append(prefix[:-1])
elif x[:len(prefix)] != prefix:
x = prefix + x

result.append(x)

if suffix:
if suffix[0] == ' ':
result.append(suffix[1:])
elif x[-len(suffix):] != suffix:
result[-1] = result[-1]+suffix

return result


Also, I need to make 2 small changes to SCons itself to help with
interpreting the command line. The first of these may be relevant to your
issues:

1) In Subst.py, function add_to_current_word, we have to uncomment
the code related to handling of literals so it looks like this:

y = current_word + x

# We used to treat a word appended to a literal
# as a literal itself, but this caused problems
# with interpreting quotes around space-separated
# targets on command lines. Removing this makes
# none of the "substantive" end-to-end tests fail,
# so we'll take this out but leave it commented
# for now in case there's a problem not covered
# by the test cases and we need to resurrect this.
literal1 = self.literal(self[-1][-1])
literal2 = self.literal(x)
y = self.conv(y)
if is_String(y):
y = CmdStringHolder(y, literal1 or literal2)
#y = CmdStringHolder(y, None)
self[-1][-1] = y

(this code used to be part of SCons (from a patch I submitted), but the
developers commented it out in later versions for some reason - probably
because mixing use of MSVS/Cygwin is not a valid enough use case. Maybe
you can provide a more valid use case)

2) In FS.py, we have to add the following to the function
entry_exists_on_disk
Otherwise, SCons won't correctly find needed .h files

elif sys.platform == 'cygwin':
return d.has_key(_my_normcase(name))


Hope that helps,
Chris





On Sun, Aug 25, 2013 at 1:08 AM, William D. Jones <thor0505 at comcast.net>wrote:


> Hello all,

>

> I am working on a moderate-sized project in my spare time and using SCons

> to manage the build. I am currently running SCons 2.2 and Python 2.7 on

> Microsoft Windows 7 64-bit Professional.

>

> My project requires use of an x86 assembler, C-compiler which understands

> Microsoft extensions and a specific linker capable of absolute

> code-positioning. To that end, I’m using the WATCOM suite of tools to build

> my source. I am aware that SCons does not have WATCOM support built-in, and

> so I have built my own rudimentary tools file for the time being. I intend

> to submit this as a patch in the near-future (but will ask for some

> guidelines beforehand). Thanks to the built-in environment variables that

> permit defining prefixes and suffixes for various options, the C compiler

> and assembler work without major issues.

>

> Unfortunately, the WATCOM linker, Wlink, has a rather esoteric command

> line syntax: all linker options must be preceded with a directive. One

> particular problem with this linker is that every file place on the command

> line must be preceded with the ‘file’ directive, or alternatively, have a

> trailing comma after each file.

>

> Assume I have 4 source files, called a.obj, b.obj, c.obj, and d.obj, and

> want to create a target e.exe. The correct way to link a file such as this

> is either of the following:

>

> wlink name e.exe option quiet file a.obj file b.obj file c.obj file d.obj

> wlink name e.exe option quiet file a.obj, b.obj, c.obj, d.obj

>

> I attempted to make sure SCons adds the file directive prefix by using the

> built-in _concat function, but concatenation

>

> env['LINK'] = 'wlink'

> #env['_LINKSOURCES'] = '${_concat("file ", SOURCES, LINKSUFFIX, __env__)}'

> #env['LINKPREFIX'] = 'file '

> #env['LINKSUFFIX'] = ''

> env['LINKCOM'] = "$LINK name '$TARGET' $LINKFLAGS $_LIBDIRFLAGS $_LIBFLAGS

> _LINKSOURCES”

>

> According to the SCons source code, SCons.Defaults, line 295 in

> _concat_ixes(), file nodes (of which $SOURCES is part) are deliberately

> skipped during _concatenation. I assume there is a logical reason for this,

> but without this, I cannot seem to create a command line which SCons will

> accept. That said, is there a means to prefix each source file with the

> appropriate ‘file ‘ directive without modifying SCons.

>

>

> Although Wlink doesn’t have a wonderful syntax, it also seems that SCons

> is modifying the command strings/arguments which are sent to the system,

> and subsequently incorrectly processed by Wlink. Without quotations around

> ‘$TARGET’, SCons doesn’t parse the $TARGET variable properly according to

> wlink, and wlink will complain about a nonexistent directory. Wlink itself

> ignores the quotes in that context, but SCons passes the quotes to the

> system. In addition, I have verified that Wlink will accept multiple files

> without trailing commas or preceding file directive using the following

> syntax:

> env['LINK'] = 'wlink'

> ...

> env['LINKCOM'] = "$LINK name '$TARGET' $LINKFLAGS $_LIBDIRFLAGS $_LIBFLAGS

> file{$SOURCES}"

>

> Using the example source files above, the new command line becomes:

> wlink name ‘e.exe’ option quiet file{a.obj b.obj c.obj d.obj"}

>

> However, for reasons I do not understand, SCons subtly changes the

> command-line so that trying to link files in this manner causes all but the

> first and last file (b.obj c.obj) to error out with ‘file not found’. This

> is consistent with not having quotes around the target with env[‘LINKCOM’].

> I believe that SCons is not setting the command line properly, because

> setting the ‘LINKCOM’ variable to the final command line directly, without

> using any other construction variables also results in a successful build

> (though of course this limits me to one possible executable :P):

> env['LINK'] = 'wlink'

> ...

> env['LINKCOM'] = "wlink name ‘e.exe’ option quiet file{a.obj b.obj c.obj

> d.obj"}

>

> I imagine I can figure out what is wrong by using debug=pdb, but I’m not

> sure how to set a breakpoint *just *before a command is executed so that

> I can see the true command line passed to the system.

>

> Due to the type of object files Wlink outputs, the need for compile for

> bare-metal hardware, and the absolute code-positing requirements, the

> linker cannot be replaced easily. But short of editing SCons itself, I do

> not see a method to get Wlink to behave properly. I am wondering if anyone

> can suggest a temporary solution that doesn’t require me to edit SCons, or

> if anyone else has experienced problems with command lines being parsed

> improperly?

>

> Thank you for your help in advance.

>

> Sincerely,

>

> --

> William D. Jones

> Rowan University | ECE | 2012

> Member IEEE

> Member Tau Beta Pi

> thor0505 at comcast.net

> Message sent using 'Windows Live Mail' client.

>

> _______________________________________________

> Scons-users mailing list

> Scons-users at scons.org

> http://four.pairlist.net/mailman/listinfo/scons-users

>

>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://four.pairlist.net/pipermail/scons-users/attachments/20130826/f38eeb50/attachment-0001.html


More information about the Scons-users mailing list