关于linux:设置临时环境($ PATH)

Set a temporary environment ($PATH)

我可能会在这个问题上陷入X-Y问题,如果我错了,我鼓励你们纠正我。

我想配置一个可以在不同平台和不同编译器版本上工作的工具链环境。我最初编写了一个长Perl脚本,生成只包含变量的配置生成文件。我想接吻,所以我没有使用automake或autoconf编写任何复杂的东西。此外,我希望重新配置过程非常快。在我的例子中,我的家里制造的./configure在不到一秒钟的时间内完成了所有的工作。我对此很满意。

不过,我补充说,使用环境变量可以使用更好的方法。我可以直接设置当前shell环境,而不是用特定变量编写makefile。例如:

1
export cc=gcc

不幸的是,$path中已经声明了一些变量。解决方案是在另一个路径前面添加新的$path:

1
2
3
4
export PATH=/new/toolchain/path:$PATH

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

我填补了这是丑陋的,我想删除旧的路径之前,添加新的。

得出结论:

  • 使用环境而不是自定义生成文件来设置生成配置是否更好?
  • 如何正确调整现有的环境变量?

  • 当我有几个变量要设置时,我编写了一个包装器脚本,然后用它作为我要修改的命令的前缀。我也可以用前缀

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

    我用包装纸

    • 设置编译器选项(如clang,设置CC变量,使配置脚本"将其视为选定的编译器"),
    • 设置区域变量,使用posix Cen_USen_US.UTF-8等进行测试。
    • 在减少的环境下进行测试,如在cron中。

    每一个包装器都完成了识别正确的PATHLD_LIBRARY_PATH和类似变量所需的工作。

    例如,我在十年前编写了这个临时脚本来测试本地的python版本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/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.2myscript。

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #!/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通常是tcsh,而我从(a)其他shell脚本,(b)目录编辑器,或(c)文本编辑器运行这些命令。它们使用posix shell(当然,对于需要特定功能的脚本除外),使得别名或函数很少使用。


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

    1
    VAR1=val1 VAR2=val2 VAR3=val3 make

    我觉得这比做清洁:

    1
    2
    3
    4
       export VAR1=val1
       export VAR2=val2
       export VAR3=val3
       make

    除非你是在一个包装脚本中,甚至可能和VAR1=val1 VAR2=val2 VAR3=val3 makeVAR变量将是make调用之前的任何变量(包括但不限于未到期和不存在的变量)。

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

    1
    2
    3
    4
    VAR1=val1\
    VAR2=val2\
    VAR3=val3\
    make

    您可以为任何UNIX命令设置这样的环境变量。炮弹会把它全部装好的。有些应用程序(如makerake将根据看起来像变量定义的参数来修改其环境(请参阅prodev paris的答案),但这取决于应用程序。


    我们都知道,最好是为一项任务集成标准工具,比如构建产品,而不是创建自己的方法。从长远来看,这种努力通常是有回报的。

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

    1
    2
    3
    4
    . /path/to/build-phone.env
    [your build commands]
    . /path/to/build-watch.env
    [your build commands]

    Is it better to use the environment instead of custom makefiles to set a build configuration?

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

    1
    2
    git clone ... my_project
    make -C my_project

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

    How to properly adjust existing environment variables?

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


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

    1
    make FOO=bar target

    其中,FOO是要用值bar设置的变量。

    注意,在这种情况下,它优先于环境定义!所以你可以很容易地覆盖你的路径变量…

    请查看此详细主题以了解更多信息:https://stackoverflow.com/a/2826178/4716013