From 1e04f2ba21f407901431d9c9302c0888a8d1936b Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Wed, 29 Jan 2025 14:38:43 -0800 Subject: [PATCH] Fix CMAKE_C[XX]_IMPLICIT_INCLUDE_DIRECTORIES (#23535) This fixes CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES for the case when we don't use compiler-auto-detection. i.e. `-DEMSCRIPTEN_FORCE_COMPILERS=OFF` which happens to be the default today. As a followup we should consider completely removing `EMSCRIPTEN_FORCE_COMPILERS`. Fixes: #23444 --- cmake/Modules/Platform/Emscripten.cmake | 35 ++++++++++++------------- test/cmake/static_lib/CMakeLists.txt | 5 ++++ test/test_other.py | 19 ++++++++++++++ 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/cmake/Modules/Platform/Emscripten.cmake b/cmake/Modules/Platform/Emscripten.cmake index 0036d4c564c0b..b8a18defe1078 100644 --- a/cmake/Modules/Platform/Emscripten.cmake +++ b/cmake/Modules/Platform/Emscripten.cmake @@ -110,6 +110,16 @@ if (NOT EMSCRIPTEN_VERSION) set(EMSCRIPTEN_VERSION "${CMAKE_MATCH_1}") endif() +execute_process(COMMAND "${EMSCRIPTEN_ROOT_PATH}/em-config${EMCC_SUFFIX}" "CACHE" + RESULT_VARIABLE _emcache_result + OUTPUT_VARIABLE _emcache_output + OUTPUT_STRIP_TRAILING_WHITESPACE) +if (NOT _emcache_result EQUAL 0) + message(FATAL_ERROR "Failed to find emscripten cache directory with command \"'${EMSCRIPTEN_ROOT_PATH}/em-config${EMCC_SUFFIX}' CACHE\"! Process returned with error code ${_emcache_result}.") +endif() +file(TO_CMAKE_PATH "${_emcache_output}" _emcache_output) +set(EMSCRIPTEN_SYSROOT "${_emcache_output}/sysroot") + # Don't allow CMake to autodetect the compiler, since this is quite slow with # Emscripten. # Pass -DEMSCRIPTEN_FORCE_COMPILERS=OFF to disable (sensible mostly only for @@ -159,6 +169,13 @@ if (EMSCRIPTEN_FORCE_COMPILERS) set(CMAKE_C_PLATFORM_ID "emscripten") set(CMAKE_CXX_PLATFORM_ID "emscripten") + if (NOT DEFINED CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES) + set(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES "${EMSCRIPTEN_SYSROOT}/include") + endif() + if (NOT DEFINED CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES) + set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "${EMSCRIPTEN_SYSROOT}/include;${EMSCRIPTEN_SYSROOT}/include/c++/v1") + endif() + if ("${CMAKE_VERSION}" VERSION_LESS "3.8") set(CMAKE_C_COMPILE_FEATURES "c_function_prototypes;c_restrict;c_variadic_macros;c_static_assert") set(CMAKE_C90_COMPILE_FEATURES "c_function_prototypes") @@ -201,16 +218,6 @@ if (EMSCRIPTEN_FORCE_COMPILERS) endif() endif() -execute_process(COMMAND "${EMSCRIPTEN_ROOT_PATH}/em-config${EMCC_SUFFIX}" "CACHE" - RESULT_VARIABLE _emcache_result - OUTPUT_VARIABLE _emcache_output - OUTPUT_STRIP_TRAILING_WHITESPACE) -if (NOT _emcache_result EQUAL 0) - message(FATAL_ERROR "Failed to find emscripten cache directory with command \"'${EMSCRIPTEN_ROOT_PATH}/em-config${EMCC_SUFFIX}' CACHE\"! Process returned with error code ${_emcache_result}.") -endif() -file(TO_CMAKE_PATH "${_emcache_output}" _emcache_output) -set(EMSCRIPTEN_SYSROOT "${_emcache_output}/sysroot") - list(APPEND CMAKE_FIND_ROOT_PATH "${EMSCRIPTEN_SYSROOT}") list(APPEND CMAKE_SYSTEM_PREFIX_PATH /) @@ -366,11 +373,3 @@ endif() # complain about unused CMake variable. if (CMAKE_CROSSCOMPILING_EMULATOR) endif() - -# TODO: CMake appends /usr/include to implicit includes; switching to use usr/include will make this redundant. -if (NOT DEFINED CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES) - set(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES "${EMSCRIPTEN_SYSROOT}/include") -endif() -if (NOT DEFINED CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES) - set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "${EMSCRIPTEN_SYSROOT}/include") -endif() diff --git a/test/cmake/static_lib/CMakeLists.txt b/test/cmake/static_lib/CMakeLists.txt index 751c68b9125ee..04cb4d7cab73b 100644 --- a/test/cmake/static_lib/CMakeLists.txt +++ b/test/cmake/static_lib/CMakeLists.txt @@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.0) project(static_library) +if (CMAKE_EXPORT_COMPILE_COMMANDS) + message(STATUS "CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES -> ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}") + set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) +endif() + # Test mode that checks that it's possible to override the file suffix # (independent of whether ar archive or LLVM bitcode file is created) # Note that "-DCMAKE_STATIC_LIBRARY_SUFFIX=foo" cannot be passed to CMake from diff --git a/test/test_other.py b/test/test_other.py index 2a18603771044..3ff1aa33aa469 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -1020,6 +1020,25 @@ def test_cmake_bitcode_static_libraries(self): err = self.expect_fail([EMCMAKE, 'cmake', test_file('cmake/static_lib'), '-DEMSCRIPTEN_GENERATE_BITCODE_STATIC_LIBRARIES=ON']) self.assertContained('EMSCRIPTEN_GENERATE_BITCODE_STATIC_LIBRARIES is not compatible with the', err) + @crossplatform + @parameterized({ + '': ([],), + 'noforce': (['-DEMSCRIPTEN_FORCE_COMPILERS=OFF'],), + }) + def test_cmake_compile_commands(self, args): + self.run_process([EMCMAKE, 'cmake', test_file('cmake/static_lib'), '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON'] + args) + self.assertExists('compile_commands.json') + compile_commands = json.load(open('compile_commands.json')) + command = compile_commands[0]['command'] + # Sometimes cmake puts the include dirs in an RSP file + rsp = [p for p in command.split() if 'includes_CXX.rsp' in p] + if rsp: + command = read_file(rsp[0][1:]) + include_dir = utils.normalize_path(cache.get_sysroot_dir('include')) + include_dir_cxx = utils.normalize_path(cache.get_sysroot_dir('include/c++/v1')) + self.assertContained(include_dir, command) + self.assertContained(include_dir_cxx, command) + @parameterized({ '': ['0'], 'suffix': ['1'],