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

Reply via email to