--preload-file doesn't work when passed to target_link_options in cmake

15 views
Skip to first unread message

Sahil Gautam

unread,
Dec 14, 2025, 7:23:15 PM (2 days ago) Dec 14
to emscripten-discuss
hi, i have been putting together an opengl application and recently i got to know about Emscripten and wasm, so i got to work to add support for wasm. i got most of the things working thanks to the demo[2]. most of the examples (in [2] and elsewhere on the internet) append to `CMAKE_EXE_LINKER_FLAGS` the wasm specific linker flags including `--preload-file ... `. i read somewhere while learning cmake "we shouldn't modify CMAKE_EXE_LINKER_FLAGS directly".. don't remember where i read that.

so i tried using `target_link_options` but the files don't load and the .data file isn't created either. i wonder if there's a better way to set these flags than directly appending to CMAKE_EXE_LINKER_FLAGS and i also wonder why target_link_options doesn't work.

i will really appreciate some help. i asked this question on an old github issue [3] as well, then got the idea of writing to the mailing list.

regards
sahil gautam

Sam Clegg

unread,
Dec 15, 2025, 1:20:50 PM (yesterday) Dec 15
to emscripte...@googlegroups.com
`target_link_options` should certainly work, and `CMAKE_EXE_LINKER_FLAGS` will also work (the downside is that it applies to all executables).

Can you build with `ninja -v` or `make VERBOSE=1` so you can see the full link command that is being used (if you are not using ninja yet I recommend switching right away).

You can then easily see if the `--preload-file` argument is passed to the linker or not.

Also, I highly recommend using `--embed-file` over `--preload-file` unless you have a specific reason not to.    Embedding files in the binary in more efficient in several ways.

cheers,
sam



--
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-disc...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/emscripten-discuss/51dc3253-10d8-4d20-a604-210ab219910cn%40googlegroups.com.

Sahil Gautam

unread,
Dec 15, 2025, 2:28:50 PM (yesterday) Dec 15
to emscripte...@googlegroups.com

the linker flags are indeed passed in both of them, but the loader module throws an error "LearnOpenGL/hello-triangle/shaders/shader.vert" file not found. i use make on linux and ninja on windows though i see your point, ninja is significantly faster. am using `--embed-file` now, thanks sam!

regards
sahil gautam

Sam Clegg

unread,
Dec 15, 2025, 2:34:25 PM (yesterday) Dec 15
to emscripte...@googlegroups.com
On Mon, Dec 15, 2025 at 11:28 AM Sahil Gautam <printfd...@gmail.com> wrote:

the linker flags are indeed passed in both of them, but the loader module throws an error "LearnOpenGL/hello-triangle/shaders/shader.vert" file not found. i use make on linux and ninja on windows though i see your point, ninja is significantly faster. am using `--embed-file` now, thanks sam!


The other reason I recommend ninja so strongly is that it shows the failing sub commands.   cmake + make will hide the commands from you, even when they fail, which causes a lot of annoying back and forth on our bug tracker :) 

Sahil Gautam

unread,
Dec 15, 2025, 3:36:04 PM (23 hours ago) Dec 15
to emscripten-discuss
building with  ninja and looking closely at the output revealed what's going on. [1] is the output with two `--embed-file path` linker flags appended to `CMAKE_EXE_LINKER_FLAGS`, and [2] is the output for the same done with `target_link_options`. as you can see, [2] clubs both of them together but emcc expected `--embed-file` to just have one argument (if i can call it that). my mistake was that i didn't read the output carefully (i was rushing towards the solution <-- real mistake). what i did to "fix" this was to add quotes around `--embed-file ..@..` linker flags, the quotes made it to the final command [3]. i thought in cmake everything (arguments) is a string, so adding quotes won't hurt.

so now i have to figure out how to pass multiple --embed-file flags to the linker. each tutorial's executable in [0] has it's own assets + the project's assets, so i need atleast two --embed-file flags. searching and reading a bit on the internet, i found [-1] i.e. one can pass a flag as "SHELL:..." and the flag would be passed as a shell string. [-2] explains it well. it works!

about ninja, it's cool! i tried looked on the internet ways to set ninja as the default generator inside the cmake file (so that i don't have to use -G). all i could find was that i can set CMAKE_GENERATOR environment variable. i then thought of editing the environment varialbe from the cmake file, but that didn't do anything `set(ENV{CMAKE_GENERATOR} "Ninja")`. so for now am setting it in the zshrc.

[-1]: https://gitlab.kitware.com/cmake/cmake/-/issues/15826#note_386473

[1]:
```
[79/79] : && /usr/lib/emscripten/emcc  -sMAX_WEBGL_VERSION=2 -sNO_DISABLE_EXCEPTION_CATCHING -sASSERTIONS=1 -sWASM=1 -sSAFE_HEAP=1 --embed-file /home/printfdebugging/repos/learnopengl/source/tutorials/hello-triangle/assets@LearnOpenGL/hello-triangle/assets/ --embed-file /home/printfdebugging/repos/learnopengl/assets@LearnOpenGL/assets/ -lGL --js-library /home/printfdebugging/repos/learnopengl/libs/emscripten-glfw/src/js/lib_emscripten_glfw3.js source/tutorials/hello-triangle/CMakeFiles/hello-triangle.dir/source/main.c.o -o source/tutorials/hello-triangle/hello-triangle.html  source/core/libcore.a  source/loader/libloader.a  libs/glad/libglad.a  libs/emscripten-glfw/libglfw3.a  libs/cglm/libcglm.a  cmake/stb/libstb_image.a  cmake/stb/libstb_include.a && :
```
[2]:
```
[79/79] : && /usr/lib/emscripten/emcc  -sMAX_WEBGL_VERSION=2 -sNO_DISABLE_EXCEPTION_CATCHING -sASSERTIONS=1 -sWASM=1 -sSAFE_HEAP=1 --embed-file /home/printfdebugging/repos/learnopengl/assets@LearnOpenGL/assets/ /home/printfdebugging/repos/learnopengl/source/tutorials/hello-triangle/assets@LearnOpenGL/hello-triangle/assets/ -lGL --js-library /home/printfdebugging/repos/learnopengl/libs/emscripten-glfw/src/js/lib_emscripten_glfw3.js source/tutorials/hello-triangle/CMakeFiles/hello-triangle.dir/source/main.c.o -o source/tutorials/hello-triangle/hello-triangle.html  source/core/libcore.a  source/loader/libloader.a  libs/glad/libglad.a  libs/emscripten-glfw/libglfw3.a  libs/cglm/libcglm.a  cmake/stb/libstb_image.a  cmake/stb/libstb_include.a && :
FAILED: [code=1] source/tutorials/hello-triangle/hello-triangle.html
: && /usr/lib/emscripten/emcc  -sMAX_WEBGL_VERSION=2 -sNO_DISABLE_EXCEPTION_CATCHING -sASSERTIONS=1 -sWASM=1 -sSAFE_HEAP=1 --embed-file /home/printfdebugging/repos/learnopengl/assets@LearnOpenGL/assets/ /home/printfdebugging/repos/learnopengl/source/tutorials/hello-triangle/assets@LearnOpenGL/hello-triangle/assets/ -lGL --js-library /home/printfdebugging/repos/learnopengl/libs/emscripten-glfw/src/js/lib_emscripten_glfw3.js source/tutorials/hello-triangle/CMakeFiles/hello-triangle.dir/source/main.c.o -o source/tutorials/hello-triangle/hello-triangle.html  source/core/libcore.a  source/loader/libloader.a  libs/glad/libglad.a  libs/emscripten-glfw/libglfw3.a  libs/cglm/libcglm.a  cmake/stb/libstb_image.a  cmake/stb/libstb_include.a && :
emcc: error: /home/printfdebugging/repos/learnopengl/source/tutorials/hello-triangle/assets@LearnOpenGL/hello-triangle/assets/: No such file or directory ("/home/printfdebugging/repos/learnopengl/source/tutorials/hello-triangle/assets@LearnOpenGL/hello-triangle/assets/" was expected to be an input file, based on the commandline arguments provided)
ninja: build stopped: subcommand failed.
```
[3]:
```
[79/79] : && /usr/lib/emscripten/emcc  -sMAX_WEBGL_VERSION=2 -sNO_DISABLE_EXCEPTION_CATCHING -sASSERTIONS=1 -sWASM=1 -sSAFE_HEAP=1 "--embed-file /home/printfdebugging/repos/learnopengl/assets@LearnOpenGL/assets/" "--embed-file /home/printfdebugging/repos/learnopengl/source/tutorials/hello-triangle/assets@LearnOpenGL/hello-triangle/assets/" -lGL --js-library /home/printfdebugging/repos/learnopengl/libs/emscripten-glfw/src/js/lib_emscripten_glfw3.js source/tutorials/hello-triangle/CMakeFiles/hello-triangle.dir/source/main.c.o -o source/tutorials/hello-triangle/hello-triangle.html  source/core/libcore.a  source/loader/libloader.a  libs/glad/libglad.a  libs/emscripten-glfw/libglfw3.a  libs/cglm/libcglm.a  cmake/stb/libstb_image.a  cmake/stb/libstb_include.a && :
```

Sam Clegg

unread,
Dec 15, 2025, 3:40:25 PM (23 hours ago) Dec 15
to emscripte...@googlegroups.com
I think you can avoid the need for the `SHELL:` hack in `target_link_options`, but using `=` instead of space in your command line flags.  e.g. `--embed-file=foo` instead of `--embed-file foo`.

Sahil Gautam

unread,
Dec 15, 2025, 4:10:03 PM (23 hours ago) Dec 15
to emscripten-discuss
that's much better, thanks!
Reply all
Reply to author
Forward
0 new messages