设置临时环境($ PATH)

时间:2015-05-18 07:51:17

标签: linux bash gcc

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

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

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

export cc=gcc

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

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

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

我填写这个很难看我想在添加新路径之前删除旧路径。

总结:

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

5 个答案:

答案 0 :(得分:3)

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

  • 应用于单个命令,例如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 别名函数。我没有为此目的使用它们,因为我的命令行shell通常是tcsh,而我从(a)其他shell脚本运行这些命令,(b)directory editor或(c){{ 3}}。那些使用POSIX shell(当然,对于需要特定功能的脚本),使别名或功能很少使用。

答案 1 :(得分: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的回答),但这取决于应用程序。

答案 2 :(得分:1)

  

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

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

git clone ... my_project
make -C my_project

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

  

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

您可能根本不需要调整它们。通过使用编译器等工具的完整路径,您可以将构建系统从环境中解放出来。

答案 3 :(得分:1)

众所周知,最好将标准工具集成到构建产品等任务中,而不是创建自己的方法。这项努力通常会带来长期回报。

话虽这么说,一个简单的方法是定义不同的环境文件(例如build-phone.env)为您的不同产品设置工作目录,PATHCC等,并为您的环境提供资源按需交互式文件:

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

答案 4 :(得分:0)

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

make FOO=bar target

FOO是您要使用值bar设置的变量。

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

有关详细信息,请查看此详细信息主题:https://stackoverflow.com/a/2826178/4716013