设置临时环境 ($PATH)

Posted

技术标签:

【中文标题】设置临时环境 ($PATH)【英文标题】:Set a temporary environment ($PATH) 【发布时间】:2015-07-29 15:16:24 【问题描述】:

我可能会遇到这个问题的 X-Y 问题,如果我错了,我鼓励你们纠正我。

我想配置一个可以在不同平台和编译器版本上工作的工具链环境。我最初编写了一个长的 Perl 脚本,它生成一个只包含变量的配置 Makefile。我想要简单,所以我没有使用 automake 或 autoconf 编写任何复杂的东西。此外,我希望重新配置过程非常快。就我而言,我自己写的./configure 在不到一秒的时间内完成了所有工作。我对此感到非常高兴。

但是我觉得我可以使用环境变量来使用更好的方法。我可以直接设置当前的 shell 环境,而不是编写带有特定变量的 Makefile。例如:

export cc=gcc

不幸的是,一些变量已经在 $PATH 中声明了。解决办法是在另一个前面加上新的$PATH:

export PATH=/new/toolchain/path:$PATH

echo $PATH
/new/toolchain/path:/old/toolchain/path:/usr/bin:/bin...

我觉得这很难看,我想在添加新路径之前删除旧路径。

总结:

    使用环境而不是自定义 makefile 来设置构建配置是否更好? 如何正确调整现有环境变量?

【问题讨论】:

您是否尝试过使用 SCons、CMake、autoconf 等高级构建系统? 好吧,CMake 使用 make 并且我希望让事情尽可能简单。所以在我的情况下 make 会更好。 Autoconf 看起来很复杂,我真的应该找到一个很好的教程。我仍然迷失了它。我真的应该看看 SCons。我不知道。 请注意:您发布的导出命令没有指向您发布的路径(缺少$ 符号)。 @MichaelJaros 对,我修好了。 Raketup 也不错。除了最基本的东西,做任何事情都很糟糕。 【参考方案1】:

当我有几个变量要设置时,我会编写一个 wrapper 脚本,然后将其用作要修改的命令的前缀。这让我也可以使用前缀

应用于单个命令,例如make,或 初始化 shell,以便后续命令使用更改后的设置。

我使用包装器

设置编译器选项(例如clang,设置CC 变量,使配置脚本“看到”它作为选择的编译器), 设置语言环境变量,使用 POSIX 测试 Cen_USen_US.UTF-8 等。 在简化的环境中进行测试,例如在cron 中。

每个包装器都会执行识别正确的PATHLD_LIBRARY_PATH 和类似变量所需的操作。

例如,我在大约十年前编写了这个临时脚本,以使用本地构建的 python 进行测试:

#!/bin/bash
ver=2.4.2
export TOP=/usr/local/python-$ver
export PATH=$TOP/bin:$PATH
export LD_LIBRARY_PATH=`newpath -n LD_LIBRARY_PATH -bd $TOP/lib $TOP/lib/gcc/i686-pc-linux-gnu/$ver`
if test -d $TOP
then
    exec $*
else
    echo no $TOP
    exit 1
fi

并将其用作with-python-2.4.2 myscript

一些包装器只是调用另一个脚本。 例如,我在 configure 脚本周围使用这个包装器来设置变量以进行交叉编译:

#!/bin/sh
# $Id: cfg-mingw,v 1.7 2014/09/20 20:49:31 tom Exp $
# configure to cross-compile using mingw32

BUILD_CC=$CC:-gcc
unset CC
unset CXX

TARGET=`choose-mingw32`

if test -n "$TARGET"
then
    PREFIX=
    test -d /usr/$TARGET && PREFIX="--prefix=/usr/$TARGET"
    cfg-normal \
            --with-build-cc=$BUILD_CC \
            --host=$TARGET \
            --target=$TARGET \
            $PREFIX "$@"
else
    echo "? cannot find MinGW compiler in path"
    exit 1
fi

其中choose-mingw32cfg-normal 是(a) 为交叉编译器查找可用目标名称和(b) 为配置脚本提供附加选项的脚本。

其他人可能会建议 shell aliasesfunctions。我不会将这些用于此目的,因为我的命令行 shell 通常是 tcsh,而我从 (a) 其他 shell 脚本、(b) directory editor 或 (c) text-editor 运行这些命令。那些使用 POSIX shell(当然,对于需要特定功能的脚本除外),使别名或功能很少使用。

【讨论】:

【参考方案2】:

您可以为特定的命令调用创建个性化环境:

VAR1=val1 VAR2=val2 VAR3=val3 make

我觉得这样做比这样做更干净:

   export VAR1=val1
   export VAR2=val2
   export VAR3=val3
   make

除非您在包装脚本中,甚至可能与 VAR1=val1 VAR2=val2 VAR3=val3 make VAR 变量将是它们在 make 调用之前的任何内容(包括但不限于未导出和不存在)。

长行不是问题,您可以随时将其拆分为多行:

VAR1=val1\
VAR2=val2\
VAR3=val3\
make

您可以为任何 Unix 命令设置这样的环境变量。 shell会全部设置好。 一些应用程序(例如makerake)会根据看起来像变量定义的参数修改它们的环境(参见prodev_paris 的答案),但这取决于应用程序。

【讨论】:

感谢您的提议。我会考虑的。【参考方案3】:

众所周知,最好为构建产品等任务集成标准工具,而不是创建自己的方法。从长远来看,这种努力通常会有所回报。

话虽如此,一个简单的方法是为您的不同产品定义不同的环境文件(例如build-phone.env)设置工作目录、PATHCC 等,并根据需要以交互方式获取您的环境文件:

. /path/to/build-phone.env
[your build commands]
. /path/to/build-watch.env
[your build commands]

【讨论】:

【参考方案4】:

使用环境而不是自定义 makefile 来设置构建配置更好吗?

构建系统的最佳实践是完全不依赖任何环境变量。因此,构建您的项目只需要:

git clone ... my_project
make -C my_project

必须设置环境变量容易出错,并可能导致构建不一致。

如何正确调整已有的环境变量?

您可能根本不需要调整这些。通过使用编译器等工具的完整路径,您可以将构建系统与环境分离。

【讨论】:

我同意你的观点,但是这可能会导致相当大的开销,因为项目必须每天重新配置几次。总是重新检查依赖关系可能需要一些时间。当基本代码只有几个 C 文件时,我总是对 ./configure 浪费多少时间印象深刻。 好吧,你可以运行 ./configure 几次,保存结果并制作一个 shell 脚本,使用特定配置调用 make,例如make-arm-v7.shmake-arv-v8.sh等。构建out-of-tree,这样你在不同目标架构之间切换时就不必清理你的构建目录。【参考方案5】:

我认为在调用 makefile 时使用直接变量定义可能会受益,如下所示:

make FOO=bar target

其中FOO 是您要设置为值bar 的变量。

请注意,在这种情况下,它优先于环境定义!因此,您可以轻松覆盖 PATH 变量...

请查看此详细主题以获取更多信息:https://***.com/a/2826178/4716013

【讨论】:

很好的解决方案,但在我的情况下,我需要设置大约 10 个变量(产品类型、架构、编译器、版本等)。总是写 make ARCH=... CC=... ... all 会适得其反 据我了解您的情况,您也许可以编写一个“简单”脚本来为您执行此操作:) 这就是我所做的。我有一个自定义 Perl 脚本,它生成主 Makefile 使用的 config.mak

以上是关于设置临时环境 ($PATH)的主要内容,如果未能解决你的问题,请参考以下文章

dos命令临时和永久设置环境变量方法

怎样在程序运行过程中设置临时环境变量

vagrant name怎么修改

Dos环境变量修改

linux环境变量怎么设置

win10怎么设置mingw环境变量