1

I'm compiling a program that uses Boost on a shared cluster. I have my own copy of gcc and most programs and libs I use in my home directory, including Boost 1.81.0. The cluster has Boost 1.66 in /usr/local/include. gcc seems to prefer these files over my local ones in some instances, leading to errors. How can I fix this?

This is the current include search list: (Edited to show the effect of -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. 

If I use -I/home/charlesprior/include (which is what I did in the example above) to try and force that to the top, gcc ignores the duplicate. If I use -I/some/other/dir/include where that includes Boost, everything compiles fine. I want to not have to do this and just make gcc use the include files in my home directory. An example of the type of error I get is:

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 

where you can see that gcc included a file from /usr/local/include, leading to errors.

16
  • Do you have /home/charlesprior/include/boost/mp11/function.hpp ? Commented Feb 28, 2023 at 18:15
  • This issue is related to build process since this decides what include paths are feed to compiler. What are you using as a build manager (or build manager generator)? make, cmake, ninja, bazel, some IDE specific project file, .... . Or maybe you are building this manually? Commented Feb 28, 2023 at 18:41
  • I couldn't resist: putting up a sign might help imgur.com/a/yl8DC4u Commented Feb 28, 2023 at 22:24
  • Yes mp11/function.hpp exists. Commented Mar 1, 2023 at 0:23
  • 1
    @alfC Since posting this question I switched my build system to cmake in the hopes of taking advantage of FindBoost. This flag only affects where cmake looks for the boost include files. If you specify the required version to match what's in my home directory, it finds the correct path (/home/charlesprior/include) anyway, but doesn't do anything to make the compiler prioritize this. My solution was to use try_compile with a small test program to see if the right version was being included. I've updated my answer with an example. Commented Mar 6, 2023 at 17:47

1 Answer 1

0

If a system directory is in the wrong place in your include search order, the only way to put it first is by using the flag -isystem (as opposed to -I). https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html

You can use CMake to try and get this right:

# 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; } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.