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?


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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.