<html><head><style type='text/css'>p { margin: 0; }</style></head><body><div style='font-family: times new roman,new york,times,serif; font-size: 12pt; color: #000000'><div>Hi,</div><div><br></div><div>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:</div><div><code class="cpp plain">C:\...\lib\gcc\x86_64-w64-mingw32\7.2.0\include\c++\cstdlib:75: error: stdlib.h: No such file or directory</code><div class="container"><div class="line number2 index1 alt1"><code class="cpp plain">at #include_next <br></code></div><div class="line number2 index1 alt1"><code class="cpp plain"><br></code></div><div class="line number2 index1 alt1"><code class="cpp plain"></code></div></div></div><div><div>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:</div><div><br></div>https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70129</div><div><br></div><div>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.</div><div>When a project or an external component tries to add them, CMake ignores this, and the search order stays unharmed.</div><br><div>if("${CMAKE_MINGW_IMPLICIT_INCLUDE_DIRECTORIES}" STREQUAL "")<br>    # Run the preprocessor in verbose mode on an empty input<br>    execute_process(<br>        COMMAND<br>            "${CMAKE_CXX_COMPILER}"<br>            "-E"<br>            "-Wp,-v"<br>            "-"<br>        INPUT_FILE "NUL" # Special Windows file, equivalent to /dev/null<br>        OUTPUT_VARIABLE _mingw_cpp_out # Capture stdout<br>        ERROR_VARIABLE _mingw_cpp_error # Capture stderr<br>    )<br>  <br>    # Create list of lines from stderr output:<br>    string(REGEX REPLACE ";" "\\\\;" _mingw_cpp_error "${_mingw_cpp_error}")<br>    string(REGEX REPLACE "\n" ";" _mingw_cpp_error "${_mingw_cpp_error}")<br>  <br>    # Look for this text block and gather the paths:<br>    #   #include  search starts here:<br>    #   C:/..../bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/include<br>    #   C:/..../bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/include-fixed<br>    #   C:/..../bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/include<br>    #   End of search list.<br>    set(_mingw_cpp_list)<br>    foreach(_mingw_cpp_line ${_mingw_cpp_error})<br>        if("${_mingw_cpp_line}" MATCHES "#include  search starts here:")<br>            # Block starts<br>            set(_mingw_cpp_state "ON")<br>        elseif("${_mingw_cpp_line}" MATCHES "End of search list.")<br>            # Block ends<br>            set(_mingw_cpp_state "OFF")<br>        elseif("${_mingw_cpp_state}")<br>            # Within block<br>            # Clean up and beautify the path<br>            string(STRIP "${_mingw_cpp_line}" _mingw_cpp_line)<br>            get_filename_component(_mingw_cpp_line ${_mingw_cpp_line} REALPATH)<br>            list(APPEND _mingw_cpp_list ${_mingw_cpp_line})<br>        endif()<br>    endforeach()<br> <br>    # Set the list in the cache, so that we don't have to run the external process again<br>     set(CMAKE_MINGW_IMPLICIT_INCLUDE_DIRECTORIES ${_mingw_cpp_list} CACHE INTERNAL "List of MinGW system include paths")<br>endif()<br> <br>list(APPEND CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES ${CMAKE_MINGW_IMPLICIT_INCLUDE_DIRECTORIES})<br>list(APPEND CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES ${CMAKE_MINGW_IMPLICIT_INCLUDE_DIRECTORIES})</div><div><br></div><div><br></div><div><div><br></div><div>My question is: shouldn't this be done within the standard CMake distribution, when using any GCC based compiler?<br></div><div><br></div><div><br></div><div>Olivier</div><div><br></div></div></div></body></html>