Cygwin 上の Scons によって呼び出される非対話型非ログイン POSIX シェルの修正された PATH を設定するにはどうすればよいですか?

Cygwin 上の Scons によって呼び出される非対話型非ログイン POSIX シェルの修正された PATH を設定するにはどうすればよいですか?

私はいくつかの別々のプロジェクト (それぞれが異なるコンパイラを使用) に取り組んでいるため、PATH にいずれかのコンパイラへのパスを設定することは好みません。

現在、私は別のプロジェクトに参加していますが、そこではコンパイラへのパスをデフォルトのシステム PATH の一部として持つのが慣例となっているようで、これを回避したいのですが、困難に陥っています。

私は Cygwin を使用して Windows 7 SP1 (64 ビット) で作業しています。

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

新しいプロジェクトでは、ビルド環境として Scons を使用します。

$ 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

新しいプロジェクトをビルドする前に実行できるスクリプトがあり、必要な環境変数をすべて適切に設定できます (基本的には、「export PATH=...」、「export INCLUDE=...」、「export LIB=...」、および「export LIBPATH=...」の長いリストです)。このスクリプトは、任意のスタートアップ ファイルから取得できます。パスは対話型 Bash セッションで設定されますが、

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

私が試すとき

$ scons -u

私は(最終的には)

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.

裏では、/bin/shは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.

これは問題にならないはずです。なぜなら、私の理解では、/bin/sh として呼び出されると、bash は POSIX シェルをエミュレートしようとするからです。おそらく、Scons の観点からは望ましい動作です。

問題は、非対話型、非ログインの POSIX シェル環境に必要な環境変数を取得する方法が見つからないことです。 誰か、その方法を教えてもらえませんか?

答え1

私は間違ったアプローチを取っていました。これを行う簡単な(しかし見苦しい)方法は、シェルが呼び出される前にプログラムによって環境を変更するトリガーが存在するように SConstruct ファイルを変更することです。

概念実証のために、ユーザー名をトリガーとして使用しました。

import getpass

そしてその後

    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;')

これはうまくいくようです。

関連情報