[CMake] CMAKE_*_IMPLICIT_INCLUDE_DIRECTORIES with MinGW

Olivier Croquette ocroquette at free.fr
Thu Nov 8 01:36:26 EST 2018


Hi everyone,

any feedback on this?
As a summary, it's about adding the default include paths of GCC to the 
variables "CMAKE_*_IMPLICIT_INCLUDE_DIRECTORIES" to avoid CMake modules 
or scripts to mess up with them, more specifically with their order.

Cheers,
Olivier


On 2018-11-3 21:41, Olivier Croquette wrote:
> 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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20181108/0ac95c72/attachment.html>


More information about the CMake mailing list