我正在编译一个在共享集群上使用Boost的程序.我的主目录中有我自己的GCC和我使用的大多数程序和库,包括Boost 1.81.0.集群的Boost 1.66位于/usr/local/Include中.在某些情况下,GCC似乎更喜欢这些文件,而不是我本地的文件,这导致了错误.我怎么才能解决这个问题呢?

这是当前的包含搜索列表: (编辑为显示-I/home/charlesprior/include的效果)

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.

如果我使用-I/home/charlesprior/include(这就是我在上面的示例中所做的)来try 强制将其添加到顶部,GCC将忽略重复项.如果我在包括Boost的地方使用-I/some/other/dir/include,一切都编译得很好.我不想这样做,只想让GCC使用我主目录中的包含文件.我收到的这类错误的一个例子是:

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_assi
gnable<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的文件,这会导致错误.

推荐答案

如果系统目录在您的包含搜索顺序中位于错误的位置,将其放在第一位的唯一方法是使用标志-isystem(而不是-I).https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html

您可以使用CMaketry 正确执行以下操作:

# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(
        BoostProject
        VERSION 1.0
        LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)

find_package(Boost 1.81.0 REQUIRED)

message(STATUS "Boost include dirs: ${Boost_INCLUDE_DIRS}")
try_compile(
        CORRECT_BOOST_VERSION
        SOURCES "${CMAKE_SOURCE_DIR}/test_boost_version.cpp"
        COMPILE_DEFINITIONS "-DBOOST_FOUND=${Boost_VERSION_MACRO}" "-I ${Boost_INCLUDE_DIRS}")

if (NOT CORRECT_BOOST_VERSION)
    message(STATUS "Boost version in standard include paths is not correct.")
    message(CHECK_START "Attempting to declare ${Boost_INCLUDE_DIRS} as a system include directory.")
    try_compile(
            SECOND_BOOST_TEST
            SOURCES "${CMAKE_SOURCE_DIR}/test_boost_version.cpp"
            COMPILE_DEFINITIONS "-DBOOST_FOUND=${Boost_VERSION_MACRO}" "-isystem ${Boost_INCLUDE_DIRS}"
            OUTPUT_VARIABLE TRY_COMPILE_OUTPUT)
    if (NOT SECOND_BOOST_TEST)
        message(FATAL_ERROR
                " Cannot compile. Something is wrong with your Boost installation.\n"
                " Output of test compile:\n"
                "${TRY_COMPILE_OUTPUT}")
    endif ()
    message(CHECK_PASS "Success")
endif ()

add_executable(main main.cpp)

if (NOT CORRECT_BOOST_VERSION)
    target_compile_options(main PRIVATE -isystem ${Boost_INCLUDE_DIRS})
else ()
    target_include_directories(main BEFORE PRIVATE ${Boost_INCLUDE_DIRS})
endif ()
// test_boost_version.cpp
#include <boost/version.hpp>
#ifndef BOOST_FOUND
#define BOOST_FOUND 0
#endif
static_assert(BOOST_VERSION == BOOST_FOUND); // BOOST_FOUND declared by CMake
int main() { return 0; }

Linux相关问答推荐

在不影响ROS2安装的情况下更新Ubuntu Linux中的CMake

Shell 脚本程序 - 从日志(log)文件中过滤磁盘空间利用率超过 80% 的行

计算与文件第一列对应的第二列中的字符串出现次数

ln命令报错target not a directory

CMake:处理静态库和共享库的正确方法

使用 grep 时如何跳过第一行和最后一行?

如何在 Linux 上使用 -grep 构建过滤间隔的命令

如何在ubuntu中通过.sh文件启动多个服务

如何彻底剥离可执行文件

在 Node.JS 中引用相对于应用程序根目录的文件的正确方法

仅在不存在时添加换行符

加密/解密在两个不同的 openssl 版本之间不能很好地工作

如何以另一个用户的身份使用 sudo 在 bash 子shell 中执行一系列命令?

为什么可执行文件操作系统依赖于?

谁决定任何数据类型或 struct 的大小(取决于 32 位或 64 位)?

如何设置errno值?

如何在 shell 脚本中向文件中添加一行?

如何通过 xmllint 使用 XSD 验证 XML 文件

构建窗口管理器

学习内核编程