CMake and --preload-file

1,003 views
Skip to first unread message

ewmailing

unread,
Apr 27, 2017, 9:14:14 AM4/27/17
to emscripten-discuss

I have multiple projects using CMake that have lots of asset files, which I would like to try building with Emscripten.


Already for cross-platform reasons, I have an explicit CMake list containing every asset file that must be bundled with the app. I would love to just pass this list to some function, similar to the em_link_js_library() function for the —js-library flag.



I did give some thought about bundling an entire directory containing resource files. Unfortunately, it isn’t always the case that all the files in a directory need to be bundled. Sometimes multiple build target (executables) share the same resource directory. Sometimes there are platform specific versions of assets in those directories that get bundled conditionally.


And I would like to avoid copying all the files to an intermediate temp directory because there are so many of them and I would hate to slow down the build every time. (And copying directories recursively is a PITA in CMake too.)



Is there already something that can be done with CMake for this?



Thanks,

Eric

Jukka Jylänki

unread,
May 5, 2017, 4:43:51 AM5/5/17
to emscripte...@googlegroups.com
Hey,

I'm doing exactly this in my own graphics engine project, where I have project source directories that contain assets. In my case, I do an asset "build" step, which processes each source asset and generates a platform specific build output from that, e.g. a compressed texture from a source texture.

In CMake, I enumerate all the asset files that need to be preloaded to the filesystem into a CMake list variable "assetFiles". With that variable, I do

if (EMSCRIPTEN)
    # Generate the command line that must be passed to emcc linker to produce the given asset list.
    set(assetBundleCmdLine "--use_preload_cache --no-heap-copy")
    foreach(assetFile ${assetFiles})
        message(STATUS "Asset path '${assetBuildDirectory}/${assetFile}@/${assetFile}'")
        set(assetBundleCmdLine "${assetBundleCmdLine} --preload-file \"${assetBuildDirectory}/${assetFile}@/${assetFile}\" ")
    endforeach()

    # Use a response file to store all the --preload-file directives so that windows max cmdline length limit won't be hit (there can be a lot of them!)
    file(WRITE "${CMAKE_BINARY_DIR}/${ProjectName}_emcc_preload_file.rsp" "${assetBundleCmdLine}")
    set(linkFlags "${linkFlags} \"@${CMAKE_BINARY_DIR}/${ProjectName}_emcc_preload_file.rsp\" -s TOTAL_MEMORY=${EMSCRIPTEN_REQUIRED_HEAP_SIZE} --shell-file \"${EMSCRIPTEN_HTML_SHELL_FILE_OUTPUT}\"")
    set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "${linkFlags}")
endif()

The above works on a per file basis, so if you have some kind of way to produce the ${assetFiles} list with only the files you need, you can produce a filesystem with just those files in it. See in particular the --preload-file src@dest notation used there, which takes a source location of a file on disk, and places it to be populated in path dest in the Emscripten filesystem.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+unsub...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages