Pārlūkot izejas kodu

Add self-executable HTML shell-file hack.
This hack allows IDE to "run" the HTML output file for Web platform as if it is an executable. This hack only works on Unix-alike host system, sorry.

Yao Wei Tjong 姚伟忠 8 gadi atpakaļ
vecāks
revīzija
db908c2be5
1 mainītis faili ar 17 papildinājumiem un 3 dzēšanām
  1. 17 3
      CMake/Modules/UrhoCommon.cmake

+ 17 - 3
CMake/Modules/UrhoCommon.cmake

@@ -1065,8 +1065,8 @@ macro (add_html_shell)
             # Create Urho3D custom HTML shell that also embeds our own project logo
             if (NOT EXISTS ${CMAKE_BINARY_DIR}/Source/shell.html)
                 file (READ ${EMSCRIPTEN_ROOT_PATH}/src/shell.html HTML_SHELL)
-                string (REPLACE "<!doctype html>" "<!-- This is a generated file. DO NOT EDIT!-->\n\n<!doctype html>" HTML_SHELL "${HTML_SHELL}")     # Stringify to preserve semicolons
-                string (REPLACE "<body>" "<body>\n\n<a href=\"https://urho3d.github.io\" title=\"Urho3D Homepage\"><img src=\"https://urho3d.github.io/assets/images/logo.png\" alt=\"link to https://urho3d.github.io\" height=\"80\" width=\"160\" /></a>\n" HTML_SHELL "${HTML_SHELL}")
+                string (REPLACE "<!doctype html>" "#!/usr/bin/env ${EMSCRIPTEN_EMRUN_BROWSER}\n<!-- This is a generated file. DO NOT EDIT!-->\n\n<!doctype html>" HTML_SHELL "${HTML_SHELL}")     # Stringify to preserve semicolons
+                string (REPLACE "<body>" "<body>\n<script>document.body.innerHTML=document.body.innerHTML.replace(/^#!.*\\n/, '');</script>\n<a href=\"https://urho3d.github.io\" title=\"Urho3D Homepage\"><img src=\"https://urho3d.github.io/assets/images/logo.png\" alt=\"link to https://urho3d.github.io\" height=\"80\" width=\"160\" /></a>\n" HTML_SHELL "${HTML_SHELL}")
                 file (WRITE ${CMAKE_BINARY_DIR}/Source/shell.html "${HTML_SHELL}")
             endif ()
             set (HTML_SHELL ${CMAKE_BINARY_DIR}/Source/shell.html)
@@ -1475,7 +1475,13 @@ macro (setup_executable)
         if (WEB AND DEST_BUNDLE_DIR)
             set (LOCATION $<TARGET_FILE_DIR:${TARGET_NAME}>)
             unset (FILES)
-            foreach (EXT data html html.map html.mem js wasm)
+            set (EXTS data html.map html.mem js wasm)
+            if (SELF_EXECUTABLE_SHELL)
+                install (TARGETS ${TARGET_NAME} RUNTIME DESTINATION ${DEST_BUNDLE_DIR})
+            else ()
+                list (APPEND EXTS html)
+            endif ()
+            foreach (EXT ${EXTS})
                 list (APPEND FILES ${LOCATION}/${TARGET_NAME}.${EXT})
             endforeach ()
             install (FILES ${FILES} DESTINATION ${DEST_BUNDLE_DIR} OPTIONAL)    # We get html.map or html.mem depend on the build configuration
@@ -1621,6 +1627,9 @@ macro (setup_main_executable)
                     get_property (EMCC_OPTION SOURCE ${FILE} PROPERTY EMCC_OPTION)
                     if (EMCC_OPTION STREQUAL shell-file)
                         list (APPEND TARGET_PROPERTIES SUFFIX .html)
+                        # Check if the shell-file is self-executable
+                        file (READ ${FILE} SHEBANG LIMIT 3)     # Workaround CMake's funny way of file I/O operation
+                        string (COMPARE EQUAL ${SHEBANG} "#!\n" SELF_EXECUTABLE_SHELL)
                         break ()
                     endif ()
                 endforeach ()
@@ -1629,6 +1638,7 @@ macro (setup_main_executable)
                     if (NOT EMCC_OPTION STREQUAL shell-file)
                         add_html_shell ()
                         list (APPEND TARGET_PROPERTIES SUFFIX .html)
+                        set (SELF_EXECUTABLE_SHELL 1)
                     endif ()
                 else ()
                     # If not using EMRUN then we need to include the emrun_prejs.js manually in order to process the request parameters as app's arguments correctly
@@ -1717,6 +1727,10 @@ macro (_setup_target)
                 list (APPEND LINK_FLAGS "--${EMCC_OPTION} ${FILE}${EMCC_FILE_ALIAS}${EMCC_EXCLUDE_FILE}")
             endif ()
         endforeach ()
+        # If it is a self-executable shell-file then change the attribute of the output file accordingly
+        if (SELF_EXECUTABLE_SHELL AND NOT CMAKE_HOST_WIN32)
+            add_custom_command (TARGET ${TARGET_NAME} POST_BUILD COMMAND chmod +x $<TARGET_FILE:${TARGET_NAME}>)
+        endif ()
     endif ()
     # Set additional linker dependencies (only work for Makefile-based generator according to CMake documentation)
     if (LINK_DEPENDS)