Hi,
I got recently build errors when introducing external dependencies in my project, the reason is that those components re-add standard SYSTEM include search paths, which changes the search order and causes #include_next to fail. The typical error message is: C:\...\lib\gcc\x86_64-w64-mingw32\7.2.0\include\c++\cstdlib:75: error: stdlib.h: No such file or directory at #include_next The following bug report against GCC describes the same issue independently of CMake, and apparently no improvement is to be expected from the compiler itself: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70129 So I rolled up my sleeves and implemented the following solution in CMake. It calls the preprocessor to get the standard include search paths and adds them to CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES and CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES. When a project or an external component tries to add them, CMake ignores this, and the search order stays unharmed. if("${CMAKE_MINGW_IMPLICIT_INCLUDE_DIRECTORIES}" STREQUAL "") # Run the preprocessor in verbose mode on an empty input execute_process( COMMAND "${CMAKE_CXX_COMPILER}" "-E" "-Wp,-v" "-" INPUT_FILE "NUL" # Special Windows file, equivalent to /dev/null OUTPUT_VARIABLE _mingw_cpp_out # Capture stdout ERROR_VARIABLE _mingw_cpp_error # Capture stderr ) # Create list of lines from stderr output: string(REGEX REPLACE ";" "\\\\;" _mingw_cpp_error "${_mingw_cpp_error}") string(REGEX REPLACE "\n" ";" _mingw_cpp_error "${_mingw_cpp_error}") # Look for this text block and gather the paths: # #include search starts here: # C:/..../bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/include # C:/..../bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/include-fixed # C:/..../bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/include # End of search list. set(_mingw_cpp_list) foreach(_mingw_cpp_line ${_mingw_cpp_error}) if("${_mingw_cpp_line}" MATCHES "#include search starts here:") # Block starts set(_mingw_cpp_state "ON") elseif("${_mingw_cpp_line}" MATCHES "End of search list.") # Block ends set(_mingw_cpp_state "OFF") elseif("${_mingw_cpp_state}") # Within block # Clean up and beautify the path string(STRIP "${_mingw_cpp_line}" _mingw_cpp_line) get_filename_component(_mingw_cpp_line ${_mingw_cpp_line} REALPATH) list(APPEND _mingw_cpp_list ${_mingw_cpp_line}) endif() endforeach() # Set the list in the cache, so that we don't have to run the external process again set(CMAKE_MINGW_IMPLICIT_INCLUDE_DIRECTORIES ${_mingw_cpp_list} CACHE INTERNAL "List of MinGW system include paths") endif() list(APPEND CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES ${CMAKE_MINGW_IMPLICIT_INCLUDE_DIRECTORIES}) list(APPEND CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES ${CMAKE_MINGW_IMPLICIT_INCLUDE_DIRECTORIES}) My question is: shouldn't this be done within the standard CMake distribution, when using any GCC based compiler? Olivier
-- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: https://cmake.org/mailman/listinfo/cmake