Browse Source

Fixed the build for web using CMake. (#1452)

* Fixed the build for web using CMake.

I found that the build for me was failing and I added some if defined checks in the core.c file where the glfwSetWindowAttrib was used. (error: implicit declaration of function 'glfwSetWindowAttrib' is invalid in C99 [-Werror,-Wimplicit-function-declaration])

I also changed some values in the toolchain file so that it correctly uses the .bat files when on windows.

* Cleaned up the additional variables (they are not important)

* Added more improvements to cmakelists

Added the option to use the system provided Emscripten toolchain to be more uniform with other libraries.

Fixed and issue which prevented example being built from cmake and also building with html extensions properly.

* Fixed ENUM to STRING because of a missed warning
hristo 4 years ago
parent
commit
6e79476650
4 changed files with 39 additions and 9 deletions
  1. 7 0
      CMakeLists.txt
  2. 12 4
      cmake/emscripten.cmake
  3. 4 5
      examples/CMakeLists.txt
  4. 16 0
      src/core.c

+ 7 - 0
CMakeLists.txt

@@ -7,6 +7,13 @@ option(ENABLE_ASAN  "Enable AddressSanitizer (ASAN) for debugging (degrades perf
 option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan) for debugging" OFF)
 option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan) for debugging" OFF)
 option(ENABLE_MSAN "Enable MemorySanitizer (MSan) for debugging (not recommended to run with ASAN)" OFF)
 option(ENABLE_MSAN "Enable MemorySanitizer (MSan) for debugging (not recommended to run with ASAN)" OFF)
 
 
+# This helps support the case where emsdk toolchain file is used
+# either by setting it with -DCMAKE_TOOLCHAIN_FILE=<path_to_emsdk>/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake
+# or by using "emcmake cmake -B build -S ." as described in https://emscripten.org/docs/compiling/Building-Projects.html
+if(EMSCRIPTEN)
+  SET(PLATFORM Web CACHE STRING "Forcing PLATFORM_WEB because EMSCRIPTEN was detected")
+endif()
+
 if(CMAKE_VERSION VERSION_LESS "3.1")
 if(CMAKE_VERSION VERSION_LESS "3.1")
   if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
   if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
     set(CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}")
     set(CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}")

+ 12 - 4
cmake/emscripten.cmake

@@ -1,12 +1,20 @@
 SET(CMAKE_SYSTEM_NAME Linux)
 SET(CMAKE_SYSTEM_NAME Linux)
+SET(CMAKE_SYSTEM_PROCESSOR x86)
+
+if (CMAKE_HOST_WIN32)
+  SET(EMSCRIPTEN_EXTENSION ".bat")
+else ()
+  SET(EMSCRIPTEN_EXTENSION "")
+endif()
+
+SET(CMAKE_C_COMPILER   emcc${EMSCRIPTEN_EXTENSION})
+SET(CMAKE_CXX_COMPILER em++${EMSCRIPTEN_EXTENSION})
 
 
-SET(CMAKE_C_COMPILER   emcc)
-SET(CMAKE_CXX_COMPILER em++)
 if(NOT DEFINED CMAKE_AR)
 if(NOT DEFINED CMAKE_AR)
-  find_program(CMAKE_AR NAMES emar)
+  find_program(CMAKE_AR NAMES emar${EMSCRIPTEN_EXTENSION})
 endif()
 endif()
 if(NOT DEFINED CMAKE_RANLIB)
 if(NOT DEFINED CMAKE_RANLIB)
-  find_program(CMAKE_RANLIB NAMES emranlib)
+  find_program(CMAKE_RANLIB NAMES emranlib${EMSCRIPTEN_EXTENSION})
 endif()
 endif()
 
 
 set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
 set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

+ 4 - 5
examples/CMakeLists.txt

@@ -28,7 +28,6 @@ if (APPLE AND NOT CMAKE_SYSTEM STRLESS "Darwin-18.0.0")
   add_definitions(-DGL_SILENCE_DEPRECATION)
   add_definitions(-DGL_SILENCE_DEPRECATION)
   MESSAGE(AUTHOR_WARNING "OpenGL is deprecated starting with macOS 10.14 (Mojave)!")
   MESSAGE(AUTHOR_WARNING "OpenGL is deprecated starting with macOS 10.14 (Mojave)!")
 endif()
 endif()
-set(OUTPUT_EXT)
 list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
 list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
 
 
 include(CheckIncludeFile)
 include(CheckIncludeFile)
@@ -85,12 +84,12 @@ elseif(${PLATFORM} MATCHES "Web")
   # Since WASM is used, ALLOW_MEMORY_GROWTH has no extra overheads
   # Since WASM is used, ALLOW_MEMORY_GROWTH has no extra overheads
   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s ALLOW_MEMORY_GROWTH=1 --no-heap-copy")
   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s ALLOW_MEMORY_GROWTH=1 --no-heap-copy")
   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html")
   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html")
-  set(OUTPUT_EXT ".html")
+  set(CMAKE_EXECUTABLE_SUFFIX ".html")
 
 
   # Remove the -rdynamic flag because otherwise emscripten
   # Remove the -rdynamic flag because otherwise emscripten
   # does not generate HTML+JS+WASM files, only a non-working
   # does not generate HTML+JS+WASM files, only a non-working
   # and fat HTML
   # and fat HTML
-  string(REPLACE "-rdynamic" "" CMAKE_SHARED_LIBRARY_LINK_C_FLAGS ${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS})
+  string(REPLACE "-rdynamic" "" CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS}")
 endif()
 endif()
 
 
 include_directories(BEFORE SYSTEM others/external/include)
 include_directories(BEFORE SYSTEM others/external/include)
@@ -103,7 +102,7 @@ endif()
 foreach(example_source ${example_sources})
 foreach(example_source ${example_sources})
   # Create the basename for the example
   # Create the basename for the example
   get_filename_component(example_name ${example_source} NAME)
   get_filename_component(example_name ${example_source} NAME)
-  string(REPLACE ".c" "${OUTPUT_EXT}" example_name ${example_name})
+  string(REPLACE ".c" "" example_name ${example_name})
 
 
   # Setup the example
   # Setup the example
   add_executable(${example_name} ${example_source})
   add_executable(${example_name} ${example_source})
@@ -125,7 +124,7 @@ if (${PLATFORM} MATCHES "Desktop")
   foreach (example_source "others/rlgl_standalone.c")
   foreach (example_source "others/rlgl_standalone.c")
     # Create the basename for the example
     # Create the basename for the example
     get_filename_component(example_name ${example_source} NAME)
     get_filename_component(example_name ${example_source} NAME)
-    string(REPLACE ".c" "${OUTPUT_EXT}" example_name ${example_name})
+    string(REPLACE ".c" "" example_name ${example_name})
     add_executable(${example_name} ${example_source})
     add_executable(${example_name} ${example_source})
     add_dependencies(${example_name} raylib)
     add_dependencies(${example_name} raylib)
     target_link_libraries(${example_name} ${raylib_LDFLAGS})
     target_link_libraries(${example_name} ${raylib_LDFLAGS})

+ 16 - 0
src/core.c

@@ -1133,15 +1133,19 @@ void SetWindowState(unsigned int flags)
     // State change: FLAG_WINDOW_RESIZABLE
     // State change: FLAG_WINDOW_RESIZABLE
     if (((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) != (flags & FLAG_WINDOW_RESIZABLE)) && ((flags & FLAG_WINDOW_RESIZABLE) > 0)) 
     if (((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) != (flags & FLAG_WINDOW_RESIZABLE)) && ((flags & FLAG_WINDOW_RESIZABLE) > 0)) 
     {
     {
+#if defined(PLATFORM_DESKTOP)
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_RESIZABLE, GLFW_TRUE);
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_RESIZABLE, GLFW_TRUE);
         CORE.Window.flags |= FLAG_WINDOW_RESIZABLE;
         CORE.Window.flags |= FLAG_WINDOW_RESIZABLE;
+#endif
     }
     }
     
     
     // State change: FLAG_WINDOW_UNDECORATED
     // State change: FLAG_WINDOW_UNDECORATED
     if (((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) != (flags & FLAG_WINDOW_UNDECORATED)) && (flags & FLAG_WINDOW_UNDECORATED)) 
     if (((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) != (flags & FLAG_WINDOW_UNDECORATED)) && (flags & FLAG_WINDOW_UNDECORATED)) 
     {
     {
+#if defined(PLATFORM_DESKTOP)
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_DECORATED, GLFW_FALSE);
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_DECORATED, GLFW_FALSE);
         CORE.Window.flags |= FLAG_WINDOW_UNDECORATED;
         CORE.Window.flags |= FLAG_WINDOW_UNDECORATED;
+#endif
     }
     }
 
 
     // State change: FLAG_WINDOW_HIDDEN
     // State change: FLAG_WINDOW_HIDDEN
@@ -1168,15 +1172,19 @@ void SetWindowState(unsigned int flags)
     // State change: FLAG_WINDOW_UNFOCUSED
     // State change: FLAG_WINDOW_UNFOCUSED
     if (((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) != (flags & FLAG_WINDOW_UNFOCUSED)) && ((flags & FLAG_WINDOW_UNFOCUSED) > 0)) 
     if (((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) != (flags & FLAG_WINDOW_UNFOCUSED)) && ((flags & FLAG_WINDOW_UNFOCUSED) > 0)) 
     {
     {
+#if defined(PLATFORM_DESKTOP)
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_FOCUS_ON_SHOW, GLFW_FALSE);
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_FOCUS_ON_SHOW, GLFW_FALSE);
         CORE.Window.flags |= FLAG_WINDOW_UNFOCUSED;
         CORE.Window.flags |= FLAG_WINDOW_UNFOCUSED;
+#endif
     }
     }
     
     
     // State change: FLAG_WINDOW_TOPMOST
     // State change: FLAG_WINDOW_TOPMOST
     if (((CORE.Window.flags & FLAG_WINDOW_TOPMOST) != (flags & FLAG_WINDOW_TOPMOST)) && ((flags & FLAG_WINDOW_TOPMOST) > 0))
     if (((CORE.Window.flags & FLAG_WINDOW_TOPMOST) != (flags & FLAG_WINDOW_TOPMOST)) && ((flags & FLAG_WINDOW_TOPMOST) > 0))
     {
     {
+#if defined(PLATFORM_DESKTOP)
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_FLOATING, GLFW_TRUE);
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_FLOATING, GLFW_TRUE);
         CORE.Window.flags |= FLAG_WINDOW_TOPMOST;
         CORE.Window.flags |= FLAG_WINDOW_TOPMOST;
+#endif
     }
     }
     
     
     // State change: FLAG_WINDOW_ALWAYS_RUN
     // State change: FLAG_WINDOW_ALWAYS_RUN
@@ -1234,15 +1242,19 @@ void ClearWindowState(unsigned int flags)
     // State change: FLAG_WINDOW_RESIZABLE
     // State change: FLAG_WINDOW_RESIZABLE
     if (((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) > 0) && ((flags & FLAG_WINDOW_RESIZABLE) > 0))
     if (((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) > 0) && ((flags & FLAG_WINDOW_RESIZABLE) > 0))
     {
     {
+#if defined(PLATFORM_DESKTOP)
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_RESIZABLE, GLFW_FALSE);
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_RESIZABLE, GLFW_FALSE);
         CORE.Window.flags &= ~FLAG_WINDOW_RESIZABLE;
         CORE.Window.flags &= ~FLAG_WINDOW_RESIZABLE;
+#endif
     }
     }
     
     
     // State change: FLAG_WINDOW_UNDECORATED
     // State change: FLAG_WINDOW_UNDECORATED
     if (((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) > 0) && ((flags & FLAG_WINDOW_UNDECORATED) > 0)) 
     if (((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) > 0) && ((flags & FLAG_WINDOW_UNDECORATED) > 0)) 
     {
     {
+#if defined(PLATFORM_DESKTOP)
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_DECORATED, GLFW_TRUE);
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_DECORATED, GLFW_TRUE);
         CORE.Window.flags &= ~FLAG_WINDOW_UNDECORATED;
         CORE.Window.flags &= ~FLAG_WINDOW_UNDECORATED;
+#endif
     }
     }
 
 
     // State change: FLAG_WINDOW_HIDDEN
     // State change: FLAG_WINDOW_HIDDEN
@@ -1267,15 +1279,19 @@ void ClearWindowState(unsigned int flags)
     // State change: FLAG_WINDOW_UNFOCUSED
     // State change: FLAG_WINDOW_UNFOCUSED
     if (((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) > 0) && ((flags & FLAG_WINDOW_UNFOCUSED) > 0)) 
     if (((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) > 0) && ((flags & FLAG_WINDOW_UNFOCUSED) > 0)) 
     {
     {
+#if defined(PLATFORM_DESKTOP)
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_FOCUS_ON_SHOW, GLFW_TRUE);
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_FOCUS_ON_SHOW, GLFW_TRUE);
         CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED;
         CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED;
+#endif
     }
     }
     
     
     // State change: FLAG_WINDOW_TOPMOST
     // State change: FLAG_WINDOW_TOPMOST
     if (((CORE.Window.flags & FLAG_WINDOW_TOPMOST) > 0) && ((flags & FLAG_WINDOW_TOPMOST) > 0))
     if (((CORE.Window.flags & FLAG_WINDOW_TOPMOST) > 0) && ((flags & FLAG_WINDOW_TOPMOST) > 0))
     {
     {
+#if defined(PLATFORM_DESKTOP)
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_FLOATING, GLFW_FALSE);
         glfwSetWindowAttrib(CORE.Window.handle, GLFW_FLOATING, GLFW_FALSE);
         CORE.Window.flags &= ~FLAG_WINDOW_TOPMOST;
         CORE.Window.flags &= ~FLAG_WINDOW_TOPMOST;
+#endif
     }
     }
     
     
     // State change: FLAG_WINDOW_ALWAYS_RUN
     // State change: FLAG_WINDOW_ALWAYS_RUN