ubuntu16.04下gcc/g++多版本共存和切换(11/14/17/20),以及在CMake文件中的相关设置

今天发现GitHub的PCL点云库的1.10.0版本已经发布快一个月了,这刚好离我在家隔离快一个月的时间差不多。果断下载其Release版本使用cmake配置编译选项并进行编译,结果发现问题怎么这么多。其实,如果不编译CUDA和GPU相关的模块的话,一般也不会存在什么问题。

结果当我我选择编译CUDA和GPU模块之后,出现各种问题,比如使用标准STL库中的shared_ptr来替换掉之前Boost库中的shared_ptr指针,结果是没有添加标准库的std名称空间,编译出现好多错误。此外,当PCL库从1.10.0版本开始全面使用C++14标准,也就是说,如果你的GCC版本太低的话可能编译无法通过。

为此,我在ubuntu16.04上通过如下的方式安装了gcc/g++的三个主要版本,即gcc-5/g++-5gcc-7/g++-7gcc-9/g++-9

# 加入源
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
# 更新源
sudo apt update

# 安装gcc5和g++5
sudo apt install gcc-5
sudo apt install g++-5
# 将gcc和g++绑定到新安装的版本上,并配置相应的数字标识,由于gcc-5和g++-5只最多支持到c++14,所以这里设置为数字14
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 14
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 14

# 安装gcc7和g++7
sudo apt install gcc-7
sudo apt install g++-7
# 将gcc和g++绑定到新安装的版本上,并配置相应的数字标识
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 17
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 17

# 安装gcc9和g++9
sudo apt install gcc-9
sudo apt install g++-9
# 将gcc和g++绑定到新安装的版本上,并配置相应的数字标识
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 20

# 此时,ubuntu16.04系统中gcc和g++编译器已经被切换成了gcc-9和g++-9
# 你可以通过下面的命令进行查看,因为默认数字越大的,优先级越高
gcc --version
g++ --version
# 不过,我们可以通过如下的命令来实现自如的切换系统当前的gcc和g++版本,即/usr/bin/gcc和/usr/bin/g++所指向的具体版本
# 切换版本
sudo update-alternatives --config gcc
sudo update-alternatives --config g++

注意: 当前的ubutnu16.04系统中,还是gcc-5/g++-5版本的最为稳定,所以通常大部分的库能用gcc-5/g++-5编译,而使用gcc-7/g++-7就无法编译通过,因为不管是gcc-7/g++-7还是gcc-9/g++-9都是非常新的版本。

接下来,为了测试不同版本的的gcc/g++编译器的调用情况,我使用CMake来构建一个简单的Demo,这里选择直到gcc-9/g++-9才纳入到标准库中的文件系统头文件,即std::filesystem,而在此之前,不管是gcc-5/g++-5还是gcc-7/g++-7都是这样的std::experimental::filesystem

下面,我们进行如下的三个测试:

现在我把ubuntu16.04系统的当前编译器设置为gcc-5/g++-5,尤其要注意你的ubuntu系统中当前被激活的gnu编译器版本,否则可能因为版本过低而无法编译基于高版本的STL标准库的程序。
CMakeLists.txt(测试gcc-5/g++-5

cmake_minimum_required(VERSION 3.16.4)
project(get_current_project_path)
set(CMAKE_CXX_STANDARD 11) //set(CMAKE_CXX_STANDARD 14) 或者 set(CMAKE_CXX_STANDARD 17)都可以编译通过
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_executable(get_current_project_path main.cpp)
target_link_libraries(${PROJECT_NAME} -lstdc++fs) //target_link_libraries(${PROJECT_NAME} libstdc++fs.a)

main.cpp

#include 
#include

int main() {
    std::cout << std::experimental::filesystem::current_path() << std::endl;
    return 0;
}

运行结果:编译通过
注意,gcc-5/g++-5版本的编译器是支持C++11/14/17的但是不支持C++20,因此当设置set(CMAKE_CXX_STANDARD 20)时是无法编译通过的,cmake会提示:Target "get_current_project_path" requires the language dialect "CXX20" , but CMake does not know the compile flags to use to enable it.

现在我把ubuntu16.04系统的当前编译器设置为gcc-7/g++-7

CMakeLists.txt(测试gcc-7/g++-7

cmake_minimum_required(VERSION 3.16.4)
project(get_current_project_path)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_executable(get_current_project_path main.cpp)
target_link_libraries(${PROJECT_NAME} -lstdc++fs) //target_link_libraries(${PROJECT_NAME} libstdc++fs.a)
#include 
#include

int main() {
    std::cout << std::experimental::filesystem::current_path() << std::endl;
    return 0;
}

运行结果:编译通过

现在我把ubuntu16.04系统的当前编译器设置为gcc-9/g++-9
CMakeLists.txt(测试gcc-9/g++-9

cmake_minimum_required(VERSION 3.16.4)
project(get_current_project_path)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_executable(get_current_project_path main.cpp) 
//注意:不再需要链接libstdc++fs.a文件,如果你使用的是 #include 
//target_link_libraries(${PROJECT_NAME} -lstdc++fs) //target_link_libraries(${PROJECT_NAME} libstdc++fs.a)

main.cpp

#include 
//#include //使用这个头文件也可以编译通过,因为gcc-9/g++-9兼容了gcc-7/g++-7
#include

int main() {
    //std::cout << std::experimental::filesystem::current_path() << std::endl;
    std::cout << std::filesystem::current_path() << std::endl;
    return 0;
}

运行结果:编译通过

总结:这篇博客主要讨论了不同版本编译器的调用方法。

你可能感兴趣的:(CPP)