摘要:  在本文中,笔者回答了编程环境配置中的常见问题,即在无root权限情况下,在非系统路径中部署一个与系统默认版本不同的gcc或g++,然后只在我们自己使用时显式指定这个高级版本的库。
 
 〓 Table of Contents 〓  
背景 很多时候当我们希望在远程服务器上部署某个软件,或者安装某个代码库的时候,会发现服务器默认的gcc或者g++版本并不符合我们的期望,例如,当我希望在dsflab的服务器上安装pytorch3d时,以下是我面临的情况:
1 2 3 4 5 6 7 8 (base) bash-4.2$ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper Target: x86_64-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux Thread model: posix gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)  
 
这是由于我们的系统gcc版本并不符合安装pytorch3d的要求 。那么在这种情况下,我们有3条路可以选:
换一台服务器(一劳永逸) 
安装低版本pytorch3d(目标降级) 
更新gcc及g++版本(直面挑战) 
 
当然我们肯定是选择第三条路,但要注意几点:
不影响其他user的使用 
我们作为user没有root权限 
 
则我们需要在无root权限情况下,在非系统路径中部署一个更高级版本的gcc或g++,然后只在我们自己使用时显式指定这个高级版本的库。
解决方案 〓 ReTURN 〓 
因地制宜 首先,不要盲目地就开始跑去下载我们需要的gcc或者g++,一般来说,很多服务器会预先配置好很多个不同版本的gcc,g++,cuda等等,默认虽然是低版本的代码库,但是user可以根据自己的需要去指定某些高版本的库。因此很有可能, 我们需要的目标版本的gcc或g++在服务器上已经有了,只需要我们去显式地指定使用它们  。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 (base) bash-4.2$ cd /usr/local/ # 一般多个版本的库都放在这个地方 (base) bash-4.2$ ls bin      cuda-10.0      cuda-10.1.105  cuda-11        cuda-11.0.207  cuda-11.4      cuda-11.5.0  cuda-11.7    cuda-11.8.0  cuda-8.0     cuda-8.0.61-1  cuda-9.1     cuda-9.2.148  etc  include  libexec  packages  software cuda     cuda-10.0.130  cuda-10.2      cuda-11.0      cuda-11.1      cuda-11.4.100  cuda-11.6    cuda-11.7.0  cuda-7.0     cuda-8.0.44  cuda-9.0       cuda-9.1.85  cuda-9.2.88   GNU  lib      man      sbin      src cuda-10  cuda-10.1      cuda-10.2.89   cuda-11.0.182  cuda-11.1.74   cuda-11.5      cuda-11.6.2  cuda-11.8    cuda-7.5     cuda-8.0.61  cuda-9.0.176   cuda-9.2     dbpackages    go   lib64    nvidia   share (base) bash-4.2$ cd GNU (base) bash-4.2$ ls autoconf         binutils         emacs        gcc-10.2.0  gcc-12.2.0  gcc6       gcc-7.2.0  gcc-8.3.0  gdbm-1.11         glpk           gnutls         libgcrypt          m4         mpfr               perl-5 autoconf-2.69    binutils-2.24    emacs-24.4   gcc-10.3.0  gcc4        gcc-6.1.0  gcc-7.3.0  gcc9       gettext           glpk-4.65      gnutls-3.3.10  libgcrypt-1.7.6    m4-1.4.17  mpfr-3.1.2         perl-5.20.1 automake         binutils-2.25.1  flex         gcc11       gcc-4.9.2   gcc-6.2.0  gcc-7.5.0  gcc-9.1.0  gettext-0.19.5.1  gmp            gperf          libgpg-error       make       mpfr-3.1.5         perl-5.22.0 automake-1.13    binutils-2.28    flex-2.5.39  gcc-11.1.0  gcc5        gcc-6.3.0  gcc8       gcc-9.2.0  glibc             gmp-6.0.0a     gperf-3.1      libgpg-error-1.27  make-4.3   parallel           readline automake-1.13.4  clisp            gcc10        gcc-11.2.0  gcc-5.3.0   gcc7       gcc-8.1.0  gcc-9.3.0  glibc-2.22        gnuplot        gsl            libsigsegv         mpc        parallel-20210722  readline-6 automake-1.15    clisp-2.49       gcc-10.1.0   gcc12       gcc-5.4.0   gcc-7.1.0  gcc-8.2.0  gdbm       glibc-2.34        gnuplot-5.0.0  gsl-1.16       libsigsegv-2.10    mpc-1.0.2  perl5              readline-6.3 
 
如我们所料,该文件下已经有各种高版本的gcc了,我们只需要在环境配置中显式指定他们就好。可以参考如下写法进行指定:
1 2 3 export  PATH=/usr/local/GNU/gcc-11.2.0/bin:$PATH export  LD_LIBRARY_PATH=/usr/local/GNU/gcc-11.2.0/lib:$LD_LIBRARY_PATH 
 
这样,当我们source环境配置后,再检查gcc以及g++版本
1 2 3 4 5 6 7 8 9 jlijz@bkzxcpu2a:/usr/local/GNU$ gcc -v Using built-in specs. COLLECT_GCC=/usr/local/bin/gcc11 COLLECT_LTO_WRAPPER=/usr/local/GNU/gcc-11.2.0/libexec/gcc/x86_64-pc-linux-gnu/11.2.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-11.2.0/configure --prefix=/usr/local/GNU/gcc-11.2.0 --enable-clocale=generic --enable-host-shared --enable-shared Thread model: posix Supported LTO compression algorithms: zlib gcc version 11.2.0 (GCC)  
 
寻求外援 〓 ReTURN 〓 
当本地确实不存在高版本的gcc,那么就必须寻求外援了。
下载 1 2 3 4 5 6 wget http://ftp.gnu.org/gnu/gcc/gcc-5.4.0/gcc-5.4.0.tar.gz # 5.4.0可以替换为你需要的版本号 tar –zxvf gcc-5.4.0.tar.gz cd gcc-5.4.0 ./contrib/download_prerequisites # 这一步是执行脚本自动下载安装所需的依赖 
 
编译安装 1 2 3 4 5 6 7 cd gcc-5.4.0 mkdir objdir   cd objdir ../configure --disable-checking --enable-languages=c,c++ --disable-multilib --prefix=/home/username/gcc-5.4 --enable-threads=posix # 我这里使用的安装路径是/home/username/gcc-5.4,大家可以换成别的路径 make -j4 //执行makefile  (过程漫长,可用多线程,但我没用) make install 
 
 注意事项  
--prefix=/home/username/gcc-5.4 这个选项的作用是指定GCC安装的目标目录。配置脚本会将编译好的GCC及其相关文件安装到这个目录中。这个路径不要填写 objdir 的绝对路径,而是填写你希望安装GCC的位置。
例如,假设你的用户名是xxx,你希望将编译好的GCC安装到你的主目录下,可以将 --prefix 设置为 /home/xxx/gcc-5.4。这样,当你运行 make install 时,GCC会被安装到这个指定的目录中。
 报错记录(1)  
相关博客 
1 2 3 4 configure: error:  *** LIBRARY_PATH shouldn't contain the current directory when *** building gcc. Please change the environment variable *** and run configure again. 
 
LD_LIBRARY_PATH以冒号结尾,GCC不赞成该冒号。 还应确保C_INCLUDE_PATH不以冒号结尾,以避免出现相关问题。 方法如下:
方法一:
重新export LIBRARY_PATH和C_INCLUDE_PATH 尾部不含冒号
方法二:
1 2 export LIBRARY_PATH=$(echo $LIBRARY_PATH | sed 's/:$//; s/^://;') export C_INCLUDE_PATH=$(echo $C_INCLUDE_PATH | sed 's/:$//; s/^://;') 
 
环境配置 〓 ReTURN 〓 
1 2 3 4 5 vim ~/.bashrc export PATH=/home/username/gcc-5.4/bin:/home/username/gcc-5.4/lib64:$PATH export LD_LIBRARY_PATH=/home/username/gcc-5.4/lib/:$LD_LIBRARY_PATH # 注意这里的path一定要和make的时候--prefix的path要对的上 source ~/.bashrc