如何為 Cygwin 上的 Scons 呼叫的非互動式非登入 POSIX shell 設定修改後的 PATH?

如何為 Cygwin 上的 Scons 呼叫的非互動式非登入 POSIX shell 設定修改後的 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=... ” ”、“導出 LIB=...”和“導出 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 shell;從 Scons 的角度來看,這可能是期望的行為。

困難在於我找不到一種方法將所需的環境變數放入非互動式、非登入的 POSIX shell 環境中。有人可以告訴我該怎麼做嗎?

答案1

我採取了錯誤的方法。執行此操作的簡單(但醜陋)方法是修改 SConstruct 文件,以便在呼叫 Shell 之前有一些觸發器以程式設計方式修改環境。

為了進行概念證明,我使用我的使用者名稱作為觸發器:

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

這似乎有效。

相關內容