Skip to content

Emscripten toolchain should point to cache sys root#133

Description

@pezcode

I mentioned this on gitter a while back but these things tend to disappear in the mist of time, so here's a trackable issue 馃崏

Corrade's Emscripten toolchain file sets CMAKE_FIND_ROOT_PATH to upstream/emscripten/system. In contrast, Emscripten's own toolchain file sets it to the cache sys root (defaults to upstream/emscripten/cache/sysroot but is configurable). The latter contains generated headers like version.h added in 3.1.4 and included directly by emscripten.h.

This breaks when you link to a library whose include path is the root include directory (like EGL) and then directly include emscripten.h. In that case, the Corrade CMAKE_FIND_ROOT_PATH has priority over the compiler's default include path, and while emscripten.h is found there, compilation fails because it now can't find version.h.

Repro: add #include <emscripten.h> to TextureGLTest.cpp on Emscripten 3.1.4 and up.

There's a rather lengthy gitter thread with more detail here.

Edit: forgot to add the patch we've been using, been working fine so far:

diff --git a/generic/Emscripten-wasm.cmake b/generic/Emscripten-wasm.cmake
index 7b6865dcee27b73cea9e2849231f5f24bb541a79..aac9d9c2c22956efd861ceb769ede19d452508f4 100644
--- a/generic/Emscripten-wasm.cmake
+++ b/generic/Emscripten-wasm.cmake
@@ -40,8 +40,6 @@ if(NOT EMSCRIPTEN_PREFIX)
     endif()
 endif()
 
-set(EMSCRIPTEN_TOOLCHAIN_PATH "${EMSCRIPTEN_PREFIX}/system")
-
 if(CMAKE_HOST_WIN32)
     set(EMCC_SUFFIX ".bat")
 else()
@@ -58,8 +56,24 @@ set(CMAKE_CXX_COMPILER "${EMSCRIPTEN_PREFIX}/em++${EMCC_SUFFIX}")
 set(CMAKE_AR "${EMSCRIPTEN_PREFIX}/emar${EMCC_SUFFIX}" CACHE PATH "Path to Emscripten ar")
 set(CMAKE_RANLIB "${EMSCRIPTEN_PREFIX}/emranlib${EMCC_SUFFIX}" CACHE PATH "Path to Emscripten ranlib")
 
+# The root path should point to the cache sysroot instead of
+# ${EMSCRIPTEN_PREFIX}/system. Otherwise, find modules may end up finding
+# include dirs in ${EMSCRIPTEN_PREFIX}/system, which is missing some generated
+# headers (e.g. version.h since 3.1.4). For example, FindEGL finds and sets the
+# root path as its include dir, and anything that links to it and includes
+# emscripten.h will fail to compile, because emscripten.h can't find version.h.
+# Taken from https://github.com/emscripten-core/emscripten/blob/74d6a15644e7f6e76ed6a1da9c6937b5cb7aef6e/cmake/Modules/Platform/Emscripten.cmake#L223
+execute_process(COMMAND "${EMSCRIPTEN_PREFIX}/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_PREFIX}/em-config${EMCC_SUFFIX}' CACHE\"! Process returned with error code ${_emcache_result}.")
+endif()
+set(EMSCRIPTEN_SYSROOT "${_emcache_output}/sysroot")
+
 set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH}
-    "${EMSCRIPTEN_TOOLCHAIN_PATH}"
+    "${EMSCRIPTEN_SYSROOT}"
     "${EMSCRIPTEN_PREFIX}")
 
 set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions