如何避免gcc搜索路径中多版本Boost引发的编译问题?
解决GCC优先选用集群旧版Boost头文件的编译问题
问题背景
共享集群环境下,主目录自行部署了gcc 12.1.0和Boost 1.81.0,但集群/usr/local/include目录存在旧版Boost 1.66。编译依赖Boost的程序时,GCC有时会优先加载旧版头文件,引发编译错误。
添加-I/home/charlesprior/include参数后,GCC头文件搜索列表如下:
GNU C++23 (GCC) version 12.1.0 (x86_64-pc-linux-gnu) compiled by GNU C version 12.1.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version none GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 ignoring nonexistent directory "/home/charlesprior/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../x86_64-pc-linux-gnu/include" ignoring duplicate directory "/home/charlesprior/include" as it is a non-system directory that duplicates a system directory #include "..." search starts here: #include <...> search starts here: /home/charlesprior/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0 /home/charlesprior/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/x86_64-pc-linux-gnu /home/charlesprior/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/backward /home/charlesprior/lib/gcc/x86_64-pc-linux-gnu/12.1.0/include /usr/local/include /home/charlesprior/include /home/charlesprior/lib/gcc/x86_64-pc-linux-gnu/12.1.0/include-fixed /usr/include End of search list.
可见/usr/local/include排在/home/charlesprior/include之前,且手动添加-I参数被判定为重复目录而忽略。
编译错误示例
In file included from /home/charlesprior/include/boost/histogram/detail/detect.hpp:11, from /home/charlesprior/include/boost/histogram/axis/traits.hpp:12, from /home/charlesprior/include/boost/histogram/indexed.hpp:12, from /home/charlesprior/include/boost/histogram/algorithm/empty.hpp:11, from /home/charlesprior/include/boost/histogram/algorithm.hpp:15, from /home/charlesprior/include/boost/histogram.hpp:27, from test.cpp:1: /usr/local/include/boost/mp11/function.hpp: In substitution of ‘template<class ... T> using variant_ca_base = boost::variant2::detail::variant _ca_base_impl<std::integral_constant<bool, (static_cast<bool>(std::is_copy_constructible<T>::value) ... && static_cast<bool>(std::is_copy_assignable<T>::value) ...)>::value, std::integral_constant<bool, (static_cast<bool>(std::is_trivially_destructible<T>::value) ... && (static_cast<bool>(std::is_trivially_copy_constructible<T>::value) ... && static_cast<bool>(std::is_trivially_copy_assignable<T>::value) ...))>::value, T ...> [with T = {T ...}]’: /home/charlesprior/include/boost/variant2/variant.hpp:1449:96: required from here /usr/local/include/boost/mp11/function.hpp:97:77: error: invalid use of pack expansion expression
错误根源是GCC加载了/usr/local/include中的旧版Boost头文件。
解决方案
1. 通过环境变量调整搜索优先级
设置CPLUS_INCLUDE_PATH环境变量,将主目录include放在最前面,让GCC优先搜索:
export CPLUS_INCLUDE_PATH="/home/charlesprior/include:$CPLUS_INCLUDE_PATH"
若要永久生效,可将该命令添加到~/.bashrc或~/.profile中。
2. 使用-isystem标记目录为系统路径
编译时用-isystem替代-I,将主目录include标记为系统目录并置于默认系统路径之前:
g++ -isystem /home/charlesprior/include test.cpp -o test
此方法会让GCC优先搜索该目录,且不会触发重复目录的警告。
3. 设置编译别名简化操作
若不想每次编译都手动添加参数,可设置g++别名:
alias g++='g++ -isystem /home/charlesprior/include'
同样可将别名添加到~/.bashrc中永久生效。
内容的提问来源于stack exchange,提问作者Charlie
相关产品推荐
相关产品推荐

