背景
机器上的当前编译器是gcc4.8,无法完全支持c++11的正则表达式,于是安装了gcc9.1.同时也修改了/usr/bin/gcc和/usr/bin/g++软连接的指向。
从下面输出可以看到,版本已经更改
[-bash-4.2 build $]gcc --version
gcc (GCC) 9.1.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
[-bash-4.2 build $]g++ --version
g++ (GCC) 9.1.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
刚开始我从命令行调用gcc进行编译,一切都很正常。后来随着代码结构逐渐复杂,每次都要在命令行敲很多字符,有点麻烦了,于是我编写了CMakeLists.txt使用cmake来构建。构建也没有报错,但是执行的时候总是会抛出异常,并且程序退出。
terminate called after throwing an instance of 'std::regex_error'
what(): regex_error
Aborted
后来使用gdb调试core文件,发现是构造std::regex对象的时候报的错误。于是怀疑是cmake默认使用的编译器版本与从命令行使用的编译器版本不一致。于是将那个导致抛出异常的std::regex对象单独拎出来,使用gcc9.1进行编译,结果不再抛出异常。
于是将cmake生成的文件全部删掉,再次执行cmake ..
结果发现:
[-bash-4.2 build $]cmake ..
-- The CXX compiler identification is GNU 4.8.5
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/Gilbert/code/regex/build
使用的编译器还是gcc4.8.5,而且编译器的文件名不是/usr/bin/g++,而是/usr/bin/c++.
为什么第一次执行cmake ..的时候没有发现呢?因为自己很确定编译器的版本已经升级到9.1了,但是并不知道原来cmake默认使用的编译器其实是/usr/bin/c++.
[-bash-4.2 build $]which c++ gcc g++
/usr/bin/c++
/usr/bin/gcc
/usr/bin/g++
[-bash-4.2 build $]ls -l $(which c++ gcc g++)
-rwxr-xr-x 4 root root 772720 Jan 20 2018 /usr/bin/c++
lrwxrwxrwx 1 root root 28 Mar 22 2023 /usr/bin/g++ -> /usr/local/gcc-9.1.0/bin/g++
lrwxrwxrwx 1 root root 28 Mar 22 2023 /usr/bin/gcc -> /usr/local/gcc-9.1.0/bin/gcc
[-bash-4.2 build $]md5sum /usr/local/gcc-9.1.0/bin/g++
73a9697e8656a9e8840c10e1779f68ab /usr/local/gcc-9.1.0/bin/g++
[-bash-4.2 build $]md5sum /usr/local/gcc-9.1.0/bin/gcc
2e4d96a0621b5d383e0d878abd8592ad /usr/local/gcc-9.1.0/bin/gcc
[-bash-4.2 build $]md5sum /usr/local/gcc-9.1.0/bin/cpp
4f3db8744854bb6dd2d55908e4a97a45 /usr/local/gcc-9.1.0/bin/cpp
[-bash-4.2 build $]md5sum /usr/local/gcc-9.1.0/bin/c++
73a9697e8656a9e8840c10e1779f68ab /usr/local/gcc-9.1.0/bin/c++
通过上面的输出可以看到,在/usr/bin目录下,有三个文件:gcc,g++,c++,其中gcc和g++都是软连接,指向gcc9.1和g++9.1,而c++是一个普通的可执行文件。通过比较编译gcc9.1产生的可执行文件可知,c++和g++的md5sum相同,可见只是文件名不同,只要将gcc9.1下面的c++复制到/usr/bin就可以解决这个问题。
这里再提供另一种解决思路:
修改环境变量CXX使其指向/usr/bin/g++,修改后可以看到cmake的输出中编译器的版本已经变成gcc9.1
[-bash-4.2 build $]export CXX=/usr/bin/g++
[-bash-4.2 build $]cmake --system-information information.txt
[-bash-4.2 build $]grep CMAKE_CXX_COMPILER information.txt
CMAKE_CXX_COMPILER "/usr/bin/c++"
CMAKE_CXX_COMPILER "/usr/bin/c++"
[-bash-4.2 build $]cmake ..
-- The CXX compiler identification is GNU 9.1.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/Gilbert/code/regex/build