How can I set a modified PATH for a non-interactive non-login POSIX shell invoked by Scons on Cygwin?

0

Because I work on a number of separate projects, (each of which uses a different compiler), I don't like to have the path to any one compiler set in my PATH.

Now I have joined another project where it seems the custom is to have the path to the compiler as part of the default system PATH, and I would like to work around this but I'm having difficulty.

I work on Windows 7 SP1, (64 bit) using Cygwin.

$ uname -srv
CYGWIN_NT-6.1 1.7.32(0.274/5/3) 2014-08-13 23:06

The new project uses Scons as the build environment:

$ scons --version
SCons by Steven Knight et al.:
    script: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
    engine: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
    engine path: ['/usr/lib/scons-2.3.4/SCons']
Copyright (c) 2001 - 2014 The SCons Foundation

I have a script that I can run (before attempting to build the new project) that will set all the required environment variables appropriately (basically it's just a long list of "export PATH=...", "export INCLUDE=...", "export LIB=..." and "export LIBPATH=..."). I can source this script from any of the start-up files, and although the path will be set in my interactive Bash session

$ which cl
/cygdrive/c/Program Files (x86)/Microsoft Visual Studio 12.0/VC/BIN/cl

when I try

$ scons -u

I get (eventually)

Compiling C++    ... Application/Infrastructure/DataManager/BitFieldDataItem/BitFieldDataItem.cpp
/bin/sh: cl: command not found
scons: *** [Build/DataManagerUnitTestWin32_Win32/Application/Infrastructure/DataManager/BitFieldDataItem/BitFieldDataItem.obj] Error 127
scons: building terminated because of errors.

Under the covers, /bin/sh is bash

$ /bin/sh --version
GNU bash, version 4.1.16(8)-release (x86_64-unknown-cygwin)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

which shouldn't be a problem because as I understand it when invoked as /bin/sh bash tries to emulate a POSIX shell; probably the desired behaviour from the point of view of Scons.

The difficulty is that I can't find a way to get the required environment variables into the non-interactive, non-login POSIX shell environment. Can someone please tell me how to do it?

Peter Du

Posted 2016-06-24T00:09:46.030

Reputation: 101

Answers

0

I was taking the wrong approach. The easy (but ugly) way to do this is to modify the SConstruct file so that there is some trigger that will modify the environment programmatically before the Shell is invoked.

For a proof of concept, I've used my username as the trigger:

import getpass

and later on

    msvcEnv = MSVCCompiler.CreateEnvironment(baseEnv)
    if getpass.getuser() == 'peterd':
        msvcEnv.PrependENVPath('PATH', '/cygdrive/c/Program Files (x86)/Microsoft SDKs/Windows/v8.1A/bin/NETFX 4.5.1 Tools/')
        msvcEnv.PrependENVPath('PATH', '/cygdrive/c/Program Files (x86)/Windows Kits/8.1/bin/x86/')
        msvcEnv.PrependENVPath('PATH', '/cygdrive/c/Program Files (x86)/Microsoft Visual Studio 12.0/Team Tools/Performance Tools/')
        msvcEnv.PrependENVPath('PATH', '/cygdrive/c/Program Files (x86)/Microsoft Visual Studio 12.0/VC/VCPackages/')
        msvcEnv.PrependENVPath('PATH', '/cygdrive/c/windows/Microsoft.NET/Framework/v4.0.30319/')
        msvcEnv.PrependENVPath('PATH', '/cygdrive/c/Program Files (x86)/Microsoft Visual Studio 12.0/Common7/Tools/')
        msvcEnv.PrependENVPath('PATH', '/cygdrive/c/Program Files (x86)/Microsoft Visual Studio 12.0/VC/BIN/')
        msvcEnv.PrependENVPath('PATH', '/cygdrive/c/Program Files (x86)/Microsoft Visual Studio 12.0/Common7/IDE/')
        msvcEnv.PrependENVPath('PATH', '/cygdrive/c/Program Files (x86)/MSBuild/12.0/bin/')
        # INCLUDE and LIBPATH are for the compiler; header files for the former, type libraries and .NET assemblies etc for the latter
        msvcEnv.PrependENVPath('INCLUDE', 'C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\winrt;C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\um;C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\shared;C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\atlmfc\include;C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\include;')
        msvcEnv.PrependENVPath('LIBPATH', 'C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v8.1\\ExtensionSDKs\\Microsoft.VCLibs\\12.0\\References\\CommonConfiguration\\neutral;C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\atlmfc\lib;C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\lib;C:\\windows\\Microsoft.NET\\Framework\\v4.0.30319;')
        # Apparently the linker still doesn't understand paths with spaces...
        msvcEnv.PrependENVPath('LIB', 'C:\\PROGRA~2\\WI3CF2~1\\8.1\\Lib\\winv6.3\\um\\x86;C:\\PROGRA~2\\MICROS~2.0\\VC\\atlmfc\\lib;C:\\PROGRA~2\\MICROS~2.0\\VC\\lib;')

This seems to work.

Peter Du

Posted 2016-06-24T00:09:46.030

Reputation: 101