[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